From 070773437da2ee67469ec3cba17c53480660c7c6 Mon Sep 17 00:00:00 2001 From: PS Date: Sat, 30 Jan 2021 13:22:43 -0800 Subject: [PATCH] began working on an abstraction layer for sockets --- src/app/blumen_lumen.cpp | 24 ++--- src/app/blumen_lumen.h | 8 ++ src/app/foldhaus_platform.h | 1 + src/app/platform_win32/win32_foldhaus.cpp | 7 +- .../platform_win32/win32_foldhaus_socket.h | 95 +++++++++++++++++++ src/gs_libs/gs_types.cpp | 95 +++++++++++++++++++ src/gs_libs/gs_types.h | 31 ++++++ 7 files changed, 245 insertions(+), 16 deletions(-) diff --git a/src/app/blumen_lumen.cpp b/src/app/blumen_lumen.cpp index e58414b..0467e8a 100644 --- a/src/app/blumen_lumen.cpp +++ b/src/app/blumen_lumen.cpp @@ -8,27 +8,23 @@ internal void BlumenLumen_MicListenJob(gs_thread_context* Ctx, u8* UserData) { - packet_ringbuffer* MicPacketBuffer = (packet_ringbuffer*)UserData; - -#if 0 - platform_socket* ListenSocket = CreateSocketAndConnect(Ctx->SocketManager, "127.0.0.1", "20185"); + mic_listen_job_data* Data = (mic_listen_job_data*)UserData; while (true) { - gs_data Data = SocketReceive(Ctx->SocketManager, &ListenSocket, Ctx->Transient); - if (Data.Size > 0) + gs_data Msg = SocketRecieve(Data->SocketManager, Data->ListenSocket, Ctx->Transient); + if (Msg.Size > 0) { OutputDebugStringA("Listened"); - MicPacketBuffer->Values[MicPacketBuffer->WriteHead++] = Data; - if (MicPacketBuffer->WriteHead >= PACKETS_MAX) + Data->MicPacketBuffer->Values[Data->MicPacketBuffer->WriteHead++] = Msg; + if (Data->MicPacketBuffer->WriteHead >= PACKETS_MAX) { - MicPacketBuffer->WriteHead = 0; + Data->MicPacketBuffer->WriteHead = 0; } } } - CloseSocket(Ctx->SocketManager, ListenSocket); -#endif + CloseSocket(Data->SocketManager, Data->ListenSocket); } internal gs_data @@ -43,7 +39,11 @@ BlumenLumen_CustomInit(app_state* State, context Context) Result = PushSizeToData(&State->Permanent, sizeof(blumen_lumen_state)); blumen_lumen_state* BLState = (blumen_lumen_state*)Result.Memory; - BLState->MicListenThread = CreateThread(Context.ThreadManager, BlumenLumen_MicListenJob, (u8*)&BLState->MicPacketBuffer); + BLState->MicListenJobData.SocketManager = Context.SocketManager; + BLState->MicListenJobData.MicPacketBuffer = &BLState->MicPacketBuffer; + BLState->MicListenJobData.ListenSocket = CreateSocket(Context.SocketManager, "127.0.0.1", "20185"); + + BLState->MicListenThread = CreateThread(Context.ThreadManager, BlumenLumen_MicListenJob, (u8*)&BLState->MicListenJobData); #if 1 diff --git a/src/app/blumen_lumen.h b/src/app/blumen_lumen.h index 74631d2..a59f26d 100644 --- a/src/app/blumen_lumen.h +++ b/src/app/blumen_lumen.h @@ -24,12 +24,20 @@ struct microphone_packet }; #pragma pack(pop) +struct mic_listen_job_data +{ + platform_socket_manager* SocketManager; + packet_ringbuffer* MicPacketBuffer; + platform_socket_handle_ ListenSocket; +}; + struct blumen_lumen_state { packet_ringbuffer MicPacketBuffer; temp_job_req JobReq; platform_thread_handle MicListenThread; + mic_listen_job_data MicListenJobData; }; diff --git a/src/app/foldhaus_platform.h b/src/app/foldhaus_platform.h index 68762b6..c3cbb3e 100644 --- a/src/app/foldhaus_platform.h +++ b/src/app/foldhaus_platform.h @@ -207,6 +207,7 @@ struct context cleanup_application* CleanupApplication; platform_thread_manager* ThreadManager; + platform_socket_manager* SocketManager; // Platform Services gs_work_queue* GeneralWorkQueue; diff --git a/src/app/platform_win32/win32_foldhaus.cpp b/src/app/platform_win32/win32_foldhaus.cpp index 0382f6d..4b4a612 100644 --- a/src/app/platform_win32/win32_foldhaus.cpp +++ b/src/app/platform_win32/win32_foldhaus.cpp @@ -496,6 +496,9 @@ WinMain ( Context.ThreadManager = PushStruct(&PlatformPermanent, platform_thread_manager); *Context.ThreadManager = CreatePlatformThreadManager(Win32CreateThread, Win32KillThread); + Context.SocketManager = PushStruct(&PlatformPermanent, platform_socket_manager); + *Context.SocketManager = CreatePlatformSocketManager(Win32CreateSocket, Win32CloseSocket, Win32SocketReceive); + win32_dll_refresh DLLRefresh = InitializeDLLHotReloading(DLLName, WorkingDLLName, DLLLockFileName); if (!ReloadAndLinkDLL(&DLLRefresh, &Context, &Win32WorkQueue.WorkQueue, true)) { return -1; } @@ -509,10 +512,6 @@ WinMain ( addressed_data_buffer_list OutputData = AddressedDataBufferList_Create(ThreadContext); - temp_job_req* Req = Context.InitializeApplication(Context); - Req->Proc = BlumenLumen_MicListenJob; - Win32_TestCode_SocketReading(ThreadContext, Req); - Running = true; Context.WindowIsVisible = true; while (Running) diff --git a/src/app/platform_win32/win32_foldhaus_socket.h b/src/app/platform_win32/win32_foldhaus_socket.h index 65fb1a2..43d5dbc 100644 --- a/src/app/platform_win32/win32_foldhaus_socket.h +++ b/src/app/platform_win32/win32_foldhaus_socket.h @@ -131,6 +131,101 @@ Win32Socket_ConnectToAddress(char* Address, char* DefaultPort) return Result; } +internal bool +Win32CreateSocket(platform_socket* Socket, char* Address, char* DefaultPort) +{ + bool Result = false; + + addrinfo Hints = {0}; + Hints.ai_family = AF_UNSPEC; + Hints.ai_socktype = SOCK_STREAM; + Hints.ai_protocol = IPPROTO_TCP; + + addrinfo* PotentialConnections; + s32 Error = getaddrinfo(Address, DefaultPort, &Hints, &PotentialConnections); + if (Error == 0) + { + for (addrinfo* InfoAt = PotentialConnections; InfoAt != NULL; InfoAt = InfoAt->ai_next) + { + SOCKET SocketHandle = socket(InfoAt->ai_family, InfoAt->ai_socktype, InfoAt->ai_protocol); + if (SocketHandle == INVALID_SOCKET) + { + Error = WSAGetLastError(); + InvalidCodePath; + } + + Error = connect(SocketHandle, InfoAt->ai_addr, (int)InfoAt->ai_addrlen); + if (Error == SOCKET_ERROR) + { + closesocket(SocketHandle); + continue; + } + else + { + Socket->PlatformHandle = (u8*)Win32Alloc(sizeof(SOCKET), 0); + *(SOCKET*)Socket->PlatformHandle = SocketHandle; + Result = true; + break; + } + } + } + else + { + Error = WSAGetLastError(); + InvalidCodePath; + } + + if (!Result) + { + Assert(Socket->PlatformHandle == 0); + } + + freeaddrinfo(PotentialConnections); + return Result; +} + +internal bool +Win32CloseSocket(platform_socket* Socket) +{ + SOCKET* Win32Sock = (SOCKET*)Socket->PlatformHandle; + closesocket(*Win32Sock); + Win32Free((u8*)Socket->PlatformHandle, sizeof(SOCKET)); + *Socket = {}; + return true; +} + +internal gs_data +Win32SocketReceive(platform_socket* Socket, gs_memory_arena* Storage) +{ + // TODO(pjs): Test this first code path when you have data running - it should + // get the actual size of the data packet being sent +#if 0 + gs_data Result = {}; + s32 BytesQueued = Win32Socket_PeekGetTotalSize(Socket); + if (BytesQueued > 0) + { + Result = PushSizeToData(Storage, BytesQueued); + s32 Flags = 0; + s32 BytesReceived = recv(Socket->Socket, (char*)Result.Memory, Result.Size, Flags); + Assert(BytesReceived == BytesQueued); + } + return Result; +#else + gs_data Result = PushSizeToData(Storage, 1024); + s32 Flags = 0; + SOCKET* Win32Sock = (SOCKET*)Socket->PlatformHandle; + s32 BytesReceived = recv(*Win32Sock, (char*)Result.Memory, Result.Size, Flags); + if (BytesReceived == SOCKET_ERROR) + { + // TODO(pjs): Error logging + s32 Error = WSAGetLastError(); + InvalidCodePath; + } + Result.Size = BytesReceived; + return Result; +#endif +} + internal s32 Win32Socket_SetOption(win32_socket* Socket, s32 Level, s32 Option, const char* OptionValue, s32 OptionLength) { diff --git a/src/gs_libs/gs_types.cpp b/src/gs_libs/gs_types.cpp index d1e6916..91f2b03 100644 --- a/src/gs_libs/gs_types.cpp +++ b/src/gs_libs/gs_types.cpp @@ -3345,6 +3345,101 @@ KillThread(platform_thread_manager* Manager, platform_thread_handle Handle) } +////////////////////////// +// +// Socket Manager + +CREATE_SOCKET(PlatformCreateSocket_Stub) +{ + return false; +} + +CLOSE_SOCKET(PlatformCloseSocket_Stub) +{ + return false; +} + +SOCKET_RECEIVE(PlatformSocketRecieve_Stub) +{ + return {}; +} + + +internal platform_socket_manager +CreatePlatformSocketManager(platform_create_socket* CreateSocketProc, + platform_close_socket* CloseSocketProc, + platform_socket_receive* SocketRecieveProc) +{ + platform_socket_manager Result = {}; + Result.CreateSocketProc = CreateSocketProc; + Result.CloseSocketProc = CloseSocketProc; + Result.SocketRecieveProc = SocketRecieveProc; + + if (!CreateSocketProc) + { + Result.CreateSocketProc = PlatformCreateSocket_Stub; + } + if (!CloseSocketProc) + { + Result.CloseSocketProc = PlatformCloseSocket_Stub; + } + if (!SocketRecieveProc) + { + Result.SocketRecieveProc = PlatformSocketRecieve_Stub; + } + return Result; +} + +internal platform_socket_handle_ +CreateSocket(platform_socket_manager* Manager, char* Addr, char* Port) +{ + platform_socket_handle_ Result = {}; + for (u32 i = 1; i < SOCKETS_COUNT_MAX; i++) + { + if (!Manager->SocketsUsed[i]) + { + Result.Index = i; + Manager->SocketsUsed[i] = true; + break; + } + } + + Assert(Result.Index != 0); + platform_socket* Socket = &Manager->Sockets[Result.Index]; + Manager->CreateSocketProc(Socket, Addr, Port); + + return Result; +} + +internal bool +CloseSocket(platform_socket_manager* Manager, platform_socket_handle_ Handle) +{ + bool Result = false; + platform_socket* Socket = &Manager->Sockets[Handle.Index]; + if (Manager->CloseSocketProc(Socket)) + { + Manager->SocketsUsed[Handle.Index] = false; + *Socket = {}; + Result = true; + } + return Result; +} + +internal gs_data +SocketRecieve(platform_socket_manager* Manager, platform_socket_handle_ SocketHandle, gs_memory_arena* Storage) +{ + gs_data Result = {}; + if (Manager->SocketsUsed[SocketHandle.Index]) + { + platform_socket* Socket = &Manager->Sockets[SocketHandle.Index]; + if (Socket->PlatformHandle != 0) + { + Result = Manager->SocketRecieveProc(Socket, Storage); + } + } + return Result; +} + /////////////////////////// // // Hashes diff --git a/src/gs_libs/gs_types.h b/src/gs_libs/gs_types.h index 8bd7ac8..2cdd56b 100644 --- a/src/gs_libs/gs_types.h +++ b/src/gs_libs/gs_types.h @@ -1086,5 +1086,36 @@ struct gs_work_queue complete_queue_work* CompleteQueueWork; }; +// Sockets + +typedef struct platform_socket_handle_ +{ + u32 Index; +} platform_socket_handle_; + +typedef struct platform_socket +{ + u8* PlatformHandle; +} platform_socket; + +#define CREATE_SOCKET(name) bool name(platform_socket* Socket, char* Addr, char* DefaultPort) +typedef CREATE_SOCKET(platform_create_socket); + +#define CLOSE_SOCKET(name) bool name(platform_socket* Socket) +typedef CLOSE_SOCKET(platform_close_socket); + +#define SOCKET_RECEIVE(name) gs_data name(platform_socket* Socket, gs_memory_arena* Storage) +typedef SOCKET_RECEIVE(platform_socket_receive); + +#define SOCKETS_COUNT_MAX 32 +typedef struct platform_socket_manager +{ + b8 SocketsUsed[SOCKETS_COUNT_MAX]; + platform_socket Sockets[SOCKETS_COUNT_MAX]; + + platform_create_socket* CreateSocketProc; + platform_close_socket* CloseSocketProc; + platform_socket_receive* SocketRecieveProc; +} platform_socket_manager; #define GS_TYPES_H #endif // GS_TYPES_H \ No newline at end of file