A better fix maybe?

This commit is contained in:
visionmercer 2026-06-23 12:33:49 +02:00
commit 96c694f78d

View file

@ -86,10 +86,12 @@ int termwidth() {
} }
int ipc_init() { int ipc_init() {
// Remove PIPE_NOWAIT so the pipe handles state transmissions reliably.
// We will handle non-blocking checks manually using PeekNamedPipe.
hServerPipe = CreateNamedPipe( hServerPipe = CreateNamedPipe(
"\\\\.\\pipe\\cimp_ipc", "\\\\.\\pipe\\cimp_ipc",
PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE, PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
1, 1,
4096, 4096,
4096, 4096,
@ -99,12 +101,11 @@ int ipc_init() {
if (hServerPipe == INVALID_HANDLE_VALUE) { if (hServerPipe == INVALID_HANDLE_VALUE) {
DWORD err = GetLastError(); DWORD err = GetLastError();
if (err == ERROR_ACCESS_DENIED || err == ERROR_PIPE_BUSY) { if (err == ERROR_ACCESS_DENIED || err == ERROR_PIPE_BUSY) {
return 0; // Already running return 0; // Already running (Client Mode)
} }
return -1; // Other error return -1; // Other error
} }
ConnectNamedPipe(hServerPipe, NULL); return 1; // Server mode successfully started
return 1;
} }
int ipc_check_message(uintptr_t buffer_ptr, int max_len) { int ipc_check_message(uintptr_t buffer_ptr, int max_len) {
@ -112,33 +113,34 @@ int ipc_check_message(uintptr_t buffer_ptr, int max_len) {
char* buffer = (char*)buffer_ptr; char* buffer = (char*)buffer_ptr;
DWORD bytesRead = 0; DWORD bytesRead = 0;
DWORD bytesAvail = 0;
// Check if a client is connected (or already connected)
BOOL connected = ConnectNamedPipe(hServerPipe, NULL) ? // Use PeekNamedPipe to see if a client has connected and written data
TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); // without blocking the main QB64 execution loop.
if (PeekNamedPipe(hServerPipe, NULL, 0, NULL, &bytesAvail, NULL)) {
if (connected) { if (bytesAvail > 0) {
DWORD bytesAvail = 0; // Data is waiting! Safely read it.
// Sneak peek to see if data has safely arrived in the buffer yet BOOL success = ReadFile(hServerPipe, buffer, max_len - 1, &bytesRead, NULL);
if (PeekNamedPipe(hServerPipe, NULL, 0, NULL, &bytesAvail, NULL)) { if (success && bytesRead > 0) {
if (bytesAvail > 0) { buffer[bytesRead] = '\0';
// Data is ready, perform the read safely
BOOL success = ReadFile(hServerPipe, buffer, max_len - 1, &bytesRead, NULL); // Disconnect and immediately reconnect to reset the pipe state for the next client
if (success && bytesRead > 0) {
buffer[bytesRead] = '\0';
DisconnectNamedPipe(hServerPipe);
ConnectNamedPipe(hServerPipe, NULL); // Re-arm for next connection
return (int)bytesRead;
}
}
} else {
// If Peek fails because the client dropped out without sending anything
if (GetLastError() == ERROR_BROKEN_PIPE) {
DisconnectNamedPipe(hServerPipe); DisconnectNamedPipe(hServerPipe);
ConnectNamedPipe(hServerPipe, NULL); return (int)bytesRead;
} }
} }
} else {
// If Peek fails because a client connected but broke the pipe/disconnected
DWORD err = GetLastError();
if (err == ERROR_BROKEN_PIPE) {
DisconnectNamedPipe(hServerPipe);
}
} }
// Non-blocking fallback: try to listen for the next incoming connection choice
// strictly if the pipe is currently completely idle.
ConnectNamedPipe(hServerPipe, NULL);
return 0; return 0;
} }