Now have thread safe plugging / unplugging of USBs / serial ports

This commit is contained in:
Peter Slattery 2021-02-20 18:21:52 -08:00
parent 0807abc08e
commit b470a63ec5
8 changed files with 121 additions and 56 deletions

View File

@ -123,7 +123,7 @@ BlumenLumen_CustomInit(app_state* State, context Context)
BLState->MicListenJobData.OutgoingMsgQueue = &BLState->OutgoingMsgQueue; BLState->MicListenJobData.OutgoingMsgQueue = &BLState->OutgoingMsgQueue;
BLState->MicListenJobData.ListenSocket = CreateSocket(Context.SocketManager, "127.0.0.1", "20185"); BLState->MicListenJobData.ListenSocket = CreateSocket(Context.SocketManager, "127.0.0.1", "20185");
BLState->MicListenThread = CreateThread(Context.ThreadManager, BlumenLumen_MicListenJob, (u8*)&BLState->MicListenJobData); //BLState->MicListenThread = CreateThread(Context.ThreadManager, BlumenLumen_MicListenJob, (u8*)&BLState->MicListenJobData);
gs_const_string SculpturePath = ConstString("data/test_blumen.fold"); gs_const_string SculpturePath = ConstString("data/test_blumen.fold");
LoadAssembly(&State->Assemblies, &State->LedSystem, State->Transient, Context, SculpturePath, State->GlobalLog); LoadAssembly(&State->Assemblies, &State->LedSystem, State->Transient, Context, SculpturePath, State->GlobalLog);

View File

@ -130,11 +130,6 @@ UART_BuildOutputData(addressed_data_buffer_list* Output, assembly_array Assembli
SLLPushOrInit(BuffersNeededHead, BuffersNeededTail, BufferSelected); SLLPushOrInit(BuffersNeededHead, BuffersNeededTail, BufferSelected);
BuffersNeededCount += 1; BuffersNeededCount += 1;
gs_string Temp = PushStringF(Transient, 256, "Found Com Port: %S\n\tStrip: %d\n", StripAt.UARTAddr.ComPort.ConstString,
StripIdx);
NullTerminate(&Temp);
OutputDebugString(Temp.Str);
} }
Assert(BufferSelected->StripIndicesCount < BufferSelected->StripIndicesCountMax); Assert(BufferSelected->StripIndicesCount < BufferSelected->StripIndicesCountMax);

View File

@ -56,6 +56,7 @@ INITIALIZE_APPLICATION(InitializeApplication)
State->LedSystem = LedSystem_Create(Context.ThreadContext.Allocator, 128); State->LedSystem = LedSystem_Create(Context.ThreadContext.Allocator, 128);
State->AssemblyDebugState = AssemblyDebug_Create(&State->Permanent); State->AssemblyDebugState = AssemblyDebug_Create(&State->Permanent);
State->AssemblyDebugState.Brightness = 255;
State->AssemblyDebugState.Override = ADS_Override_AllRed; State->AssemblyDebugState.Override = ADS_Override_AllRed;
GlobalDebugServices->Interface.RenderSculpture = true; GlobalDebugServices->Interface.RenderSculpture = true;

View File

@ -404,6 +404,10 @@ Win32_SendAddressedDataBuffer(gs_thread_context Context, addressed_data_buffer*
BuffersSent += 1; BuffersSent += 1;
DataSizeSent += BufferAt->Data.Size; DataSizeSent += BufferAt->Data.Size;
} }
else
{
Win32SerialArray_Close(BufferAt->ComPort);
}
} }
} }
else else
@ -497,7 +501,7 @@ WinMain (
*Context.ThreadManager = CreatePlatformThreadManager(Win32CreateThread, Win32KillThread); *Context.ThreadManager = CreatePlatformThreadManager(Win32CreateThread, Win32KillThread);
Context.SocketManager = PushStruct(&PlatformPermanent, platform_socket_manager); Context.SocketManager = PushStruct(&PlatformPermanent, platform_socket_manager);
*Context.SocketManager = CreatePlatformSocketManager(Win32CreateSocket, Win32CloseSocket, Win32SocketQueryStatus, Win32SocketPeek, Win32SocketReceive, Win32SocketSend); *Context.SocketManager = CreatePlatformSocketManager(Win32ConnectSocket, Win32CloseSocket, Win32SocketQueryStatus, Win32SocketPeek, Win32SocketReceive, Win32SocketSend);
win32_dll_refresh DLLRefresh = InitializeDLLHotReloading(DLLName, WorkingDLLName, DLLLockFileName); win32_dll_refresh DLLRefresh = InitializeDLLHotReloading(DLLName, WorkingDLLName, DLLLockFileName);
if (!ReloadAndLinkDLL(&DLLRefresh, &Context, &Win32WorkQueue.WorkQueue, true)) { return -1; } if (!ReloadAndLinkDLL(&DLLRefresh, &Context, &Win32WorkQueue.WorkQueue, true)) { return -1; }
@ -546,7 +550,7 @@ WinMain (
Context.UpdateAndRender(&Context, InputQueue, &RenderBuffer, &OutputData); Context.UpdateAndRender(&Context, InputQueue, &RenderBuffer, &OutputData);
bool Multithread = true; bool Multithread = false;
if (Multithread) if (Multithread)
{ {
for (addressed_data_buffer* At = OutputData.Root; for (addressed_data_buffer* At = OutputData.Root;

View File

@ -6,9 +6,9 @@
#ifndef WIN32_SERIAL_H #ifndef WIN32_SERIAL_H
global u32 Win32SerialHandlesCountMax; global u32 Win32SerialHandlesCountMax;
global u32 Win32SerialHandlesCount;
global HANDLE* Win32SerialHandles; global HANDLE* Win32SerialHandles;
global gs_string* Win32SerialPortNames; global gs_string* Win32SerialPortNames;
global s32* Win32SerialPortFilled;
DCB DCB
Win32SerialPort_GetState(HANDLE ComPortHandle) Win32SerialPort_GetState(HANDLE ComPortHandle)
@ -137,7 +137,18 @@ Win32SerialPort_Write(HANDLE PortHandle, gs_data Buffer)
{ {
OutputDebugStringA("Error: Unable to write to port\n"); OutputDebugStringA("Error: Unable to write to port\n");
s32 Error = GetLastError(); s32 Error = GetLastError();
//InvalidCodePath; switch (Error)
{
case ERROR_OPERATION_ABORTED:
case ERROR_GEN_FAILURE:
{
// NOTE(pjs): Probably means that the serial port became invalid
// ie. the usb stick was removed
}break;
case ERROR_INVALID_HANDLE:
InvalidDefaultCase;
}
} }
return Success; return Success;
@ -183,12 +194,15 @@ Win32SerialArray_Create(gs_thread_context Context)
DEBUG_TRACK_FUNCTION; DEBUG_TRACK_FUNCTION;
Win32SerialHandlesCountMax = 32; Win32SerialHandlesCountMax = 32;
Win32SerialHandlesCount = 0;
Win32SerialHandles = AllocatorAllocArray(Context.Allocator, HANDLE, Win32SerialHandlesCountMax); Win32SerialHandles = AllocatorAllocArray(Context.Allocator, HANDLE, Win32SerialHandlesCountMax);
Win32SerialPortNames = AllocatorAllocArray(Context.Allocator, gs_string, Win32SerialHandlesCountMax); Win32SerialPortNames = AllocatorAllocArray(Context.Allocator, gs_string, Win32SerialHandlesCountMax);
Win32SerialPortFilled = AllocatorAllocArray(Context.Allocator, s32, Win32SerialHandlesCountMax);
for (u32 i = 0; i < Win32SerialHandlesCountMax; i++) for (u32 i = 0; i < Win32SerialHandlesCountMax; i++)
{ {
Win32SerialPortNames[i] = AllocatorAllocString(Context.Allocator, 256); Win32SerialPortNames[i] = AllocatorAllocString(Context.Allocator, 256);
Win32SerialPortFilled[i] = 0;
} }
} }
@ -197,10 +211,28 @@ Win32SerialArray_Push(HANDLE SerialHandle, gs_const_string PortName)
{ {
DEBUG_TRACK_FUNCTION; DEBUG_TRACK_FUNCTION;
Assert(Win32SerialHandlesCount < Win32SerialHandlesCountMax); bool Found = false;
u32 Index = Win32SerialHandlesCount++; for (u32 i = 0; i < Win32SerialHandlesCountMax; i++)
Win32SerialHandles[Index] = SerialHandle; {
PrintF(&Win32SerialPortNames[Index], "%S", PortName); bool WasFilled = InterlockedCompareExchange((LONG volatile*)Win32SerialPortFilled + i, 1, 0);
if (!WasFilled)
{
Win32SerialHandles[i] = SerialHandle;
PrintF(&Win32SerialPortNames[i], "%S", PortName);
Found = true;
break;
}
}
Assert(Found);
}
void
Win32SerialArray_Pop(u32 Index)
{
bool WasFilled = InterlockedCompareExchange((LONG volatile*)Win32SerialPortFilled + Index, 0, 1);
Assert(WasFilled);
Win32SerialPortFilled[Index] = false;
Win32SerialHandles[Index] = INVALID_HANDLE_VALUE;
} }
HANDLE HANDLE
@ -209,9 +241,10 @@ Win32SerialArray_Get(gs_const_string PortName)
DEBUG_TRACK_FUNCTION; DEBUG_TRACK_FUNCTION;
HANDLE PortHandle = INVALID_HANDLE_VALUE; HANDLE PortHandle = INVALID_HANDLE_VALUE;
for (u32 i = 0; i < Win32SerialHandlesCount; i++) for (u32 i = 0; i < Win32SerialHandlesCountMax; i++)
{ {
if (StringsEqual(Win32SerialPortNames[i].ConstString, PortName)) if (Win32SerialPortFilled[i] &&
StringsEqual(Win32SerialPortNames[i].ConstString, PortName))
{ {
PortHandle = Win32SerialHandles[i]; PortHandle = Win32SerialHandles[i];
break; break;
@ -239,5 +272,19 @@ Win32SerialArray_GetOrOpen(gs_const_string PortName, u32 BaudRate, u8 ByteSize,
return PortHandle; return PortHandle;
} }
void
Win32SerialArray_Close(gs_const_string PortName)
{
for (u32 i = 0; i < Win32SerialHandlesCountMax; i++)
{
if (Win32SerialPortFilled[i] && StringsEqual(Win32SerialPortNames[i].ConstString, PortName))
{
Win32SerialPort_Close(Win32SerialHandles[i]);
Win32SerialArray_Pop(i);
break;
}
}
}
#define WIN32_SERIAL_H #define WIN32_SERIAL_H
#endif // WIN32_SERIAL_H #endif // WIN32_SERIAL_H

View File

@ -132,7 +132,7 @@ Win32Socket_ConnectToAddress(char* Address, char* DefaultPort)
} }
internal bool internal bool
Win32CreateSocket(platform_socket* Socket, char* Address, char* DefaultPort) Win32ConnectSocket(platform_socket* Socket)
{ {
bool Result = false; bool Result = false;
@ -142,7 +142,7 @@ Win32CreateSocket(platform_socket* Socket, char* Address, char* DefaultPort)
Hints.ai_protocol = IPPROTO_TCP; Hints.ai_protocol = IPPROTO_TCP;
addrinfo* PotentialConnections; addrinfo* PotentialConnections;
s32 Error = getaddrinfo(Address, DefaultPort, &Hints, &PotentialConnections); s32 Error = getaddrinfo(Socket->Addr, Socket->Port, &Hints, &PotentialConnections);
if (Error == 0) if (Error == 0)
{ {
for (addrinfo* InfoAt = PotentialConnections; InfoAt != NULL; InfoAt = InfoAt->ai_next) for (addrinfo* InfoAt = PotentialConnections; InfoAt != NULL; InfoAt = InfoAt->ai_next)
@ -175,7 +175,7 @@ Win32CreateSocket(platform_socket* Socket, char* Address, char* DefaultPort)
FD_ZERO(&SocketSet); FD_ZERO(&SocketSet);
FD_SET(SocketHandle, &SocketSet); FD_SET(SocketHandle, &SocketSet);
Assert(FD_ISSET(SocketHandle, &SocketSet)); Assert(FD_ISSET(SocketHandle, &SocketSet));
Status = select(0, &SocketSet, 0, 0, {}); Status = select(0, &SocketSet, 0, 0, (const TIMEVAL*)&Timeout);
if (Status == SOCKET_ERROR) if (Status == SOCKET_ERROR)
{ {
@ -196,7 +196,6 @@ Win32CreateSocket(platform_socket* Socket, char* Address, char* DefaultPort)
} }
} }
Socket->PlatformHandle = (u8*)Win32Alloc(sizeof(SOCKET), 0); Socket->PlatformHandle = (u8*)Win32Alloc(sizeof(SOCKET), 0);
*(SOCKET*)Socket->PlatformHandle = SocketHandle; *(SOCKET*)Socket->PlatformHandle = SocketHandle;
Result = true; Result = true;
@ -429,17 +428,17 @@ Win32Socket_Receive(win32_socket* Socket, gs_memory_arena* Storage)
{ {
// TODO(pjs): Error logging // TODO(pjs): Error logging
s32 Error = WSAGetLastError(); s32 Error = WSAGetLastError();
if (Error == 10053) switch (Error)
{ {
// WSAECONNABORTED - aborted by the software case WSAECONNABORTED:
} case WSANOTINITIALISED:
else if (Error == 10093) break;
{
// WSANOTINITIALISED case WSAENOTCONN:
} {
else
{ }break;
InvalidCodePath; InvalidDefaultCase;
} }
} }
Result.Size = BytesReceived; Result.Size = BytesReceived;

View File

@ -3349,7 +3349,7 @@ KillThread(platform_thread_manager* Manager, platform_thread_handle Handle)
// //
// Socket Manager // Socket Manager
CREATE_SOCKET(PlatformCreateSocket_Stub) CONNECT_SOCKET(PlatformConnectSocket_Stub)
{ {
return false; return false;
} }
@ -3380,7 +3380,7 @@ SOCKET_SEND(PlatformSocketSend_Stub)
} }
internal platform_socket_manager internal platform_socket_manager
CreatePlatformSocketManager(platform_create_socket* CreateSocketProc, CreatePlatformSocketManager(platform_connect_socket* ConnectSocketProc,
platform_close_socket* CloseSocketProc, platform_close_socket* CloseSocketProc,
platform_socket_query_status* SocketQueryStatusProc, platform_socket_query_status* SocketQueryStatusProc,
platform_socket_peek* SocketPeekProc, platform_socket_peek* SocketPeekProc,
@ -3388,16 +3388,16 @@ CreatePlatformSocketManager(platform_create_socket* CreateSocketProc,
platform_socket_send* SocketSendProc) platform_socket_send* SocketSendProc)
{ {
platform_socket_manager Result = {}; platform_socket_manager Result = {};
Result.CreateSocketProc = CreateSocketProc; Result.ConnectSocketProc = ConnectSocketProc;
Result.CloseSocketProc = CloseSocketProc; Result.CloseSocketProc = CloseSocketProc;
Result.SocketQueryStatusProc = SocketQueryStatusProc; Result.SocketQueryStatusProc = SocketQueryStatusProc;
Result.SocketPeekProc = SocketPeekProc; Result.SocketPeekProc = SocketPeekProc;
Result.SocketRecieveProc = SocketRecieveProc; Result.SocketRecieveProc = SocketRecieveProc;
Result.SocketSendProc = SocketSendProc; Result.SocketSendProc = SocketSendProc;
if (!CreateSocketProc) if (!ConnectSocketProc)
{ {
Result.CreateSocketProc = PlatformCreateSocket_Stub; Result.ConnectSocketProc = PlatformConnectSocket_Stub;
} }
if (!CloseSocketProc) if (!CloseSocketProc)
{ {
@ -3422,6 +3422,33 @@ CreatePlatformSocketManager(platform_create_socket* CreateSocketProc,
return Result; return Result;
} }
internal platform_socket*
SocketManagerGetSocket(platform_socket_manager* Manager, platform_socket_handle_ Handle)
{
platform_socket* Result = 0;
if (Manager->SocketsUsed[Handle.Index])
{
platform_socket* Socket = &Manager->Sockets[Handle.Index];
if (Socket->PlatformHandle != 0)
{
Result = Socket;
}
}
return Result;
}
internal bool
ConnectSocket(platform_socket_manager* Manager, platform_socket_handle_ Handle)
{
bool Result = false;
platform_socket* Socket = SocketManagerGetSocket(Manager, Handle);
if (Socket)
{
Result = Manager->ConnectSocketProc(Socket);
}
return Result;
}
internal platform_socket_handle_ internal platform_socket_handle_
CreateSocket(platform_socket_manager* Manager, char* Addr, char* Port) CreateSocket(platform_socket_manager* Manager, char* Addr, char* Port)
{ {
@ -3438,23 +3465,12 @@ CreateSocket(platform_socket_manager* Manager, char* Addr, char* Port)
Assert(Result.Index != 0); Assert(Result.Index != 0);
platform_socket* Socket = &Manager->Sockets[Result.Index]; platform_socket* Socket = &Manager->Sockets[Result.Index];
Manager->CreateSocketProc(Socket, Addr, Port); CopyArray(Addr, Socket->Addr, char, CStringLength(Addr) + 1);
CopyArray(Port, Socket->Port, char, CStringLength(Port) + 1);
bool Success = Manager->ConnectSocketProc(Socket);
Assert(Success);
return Result;
}
internal platform_socket*
SocketManagerGetSocket(platform_socket_manager* Manager, platform_socket_handle_ Handle)
{
platform_socket* Result = 0;
if (Manager->SocketsUsed[Handle.Index])
{
platform_socket* Socket = &Manager->Sockets[Handle.Index];
if (Socket->PlatformHandle != 0)
{
Result = Socket;
}
}
return Result; return Result;
} }

View File

@ -575,7 +575,8 @@ CStringLength(char* Str)
{ {
char* At = Str; char* At = Str;
while (*At) { At++; } while (*At) { At++; }
return PointerDifference(At, Str); u64 Result = PointerDifference(At, Str);
return Result;
} }
#define StringExpand(str) (int)(str).Length, (str).Str #define StringExpand(str) (int)(str).Length, (str).Str
@ -1095,11 +1096,13 @@ typedef struct platform_socket_handle_
typedef struct platform_socket typedef struct platform_socket
{ {
char Addr[128];
char Port[32];
u8* PlatformHandle; u8* PlatformHandle;
} platform_socket; } platform_socket;
#define CREATE_SOCKET(name) bool name(platform_socket* Socket, char* Addr, char* DefaultPort) #define CONNECT_SOCKET(name) bool name(platform_socket* Socket)
typedef CREATE_SOCKET(platform_create_socket); typedef CONNECT_SOCKET(platform_connect_socket);
#define CLOSE_SOCKET(name) bool name(platform_socket* Socket) #define CLOSE_SOCKET(name) bool name(platform_socket* Socket)
typedef CLOSE_SOCKET(platform_close_socket); typedef CLOSE_SOCKET(platform_close_socket);
@ -1126,7 +1129,7 @@ typedef struct platform_socket_manager
b8 SocketsUsed[SOCKETS_COUNT_MAX]; b8 SocketsUsed[SOCKETS_COUNT_MAX];
platform_socket Sockets[SOCKETS_COUNT_MAX]; platform_socket Sockets[SOCKETS_COUNT_MAX];
platform_create_socket* CreateSocketProc; platform_connect_socket* ConnectSocketProc;
platform_close_socket* CloseSocketProc; platform_close_socket* CloseSocketProc;
platform_socket_query_status* SocketQueryStatusProc; platform_socket_query_status* SocketQueryStatusProc;
platform_socket_peek* SocketPeekProc; platform_socket_peek* SocketPeekProc;