mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-19 21:28:50 +00:00
ipc: Tidy Windows mainloop code
This commit is contained in:
parent
8271d213f5
commit
fb15e8aa50
|
@ -32,30 +32,74 @@
|
||||||
|
|
||||||
#include <conio.h>
|
#include <conio.h>
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Static functions.
|
* Static functions.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
|
||||||
ipc_server_create_another_pipe_instance(struct ipc_server *vs, struct ipc_server_mainloop *ml)
|
static bool
|
||||||
|
create_pipe_instance(struct ipc_server_mainloop *ml, bool first)
|
||||||
{
|
{
|
||||||
ml->pipe_handle =
|
DWORD dwOpenMode = PIPE_ACCESS_DUPLEX;
|
||||||
CreateNamedPipeA(ml->pipe_name, PIPE_ACCESS_DUPLEX,
|
DWORD dwPipeMode = PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_NOWAIT | PIPE_REJECT_REMOTE_CLIENTS;
|
||||||
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_NOWAIT | PIPE_REJECT_REMOTE_CLIENTS,
|
|
||||||
IPC_MAX_CLIENTS, IPC_BUF_SIZE, IPC_BUF_SIZE, 0, NULL);
|
if (first) {
|
||||||
if (ml->pipe_handle == INVALID_HANDLE_VALUE) {
|
dwOpenMode |= FILE_FLAG_FIRST_PIPE_INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ml->pipe_handle = CreateNamedPipeA( //
|
||||||
|
ml->pipe_name, //
|
||||||
|
dwOpenMode, //
|
||||||
|
dwPipeMode, //
|
||||||
|
IPC_MAX_CLIENTS, //
|
||||||
|
IPC_BUF_SIZE, //
|
||||||
|
IPC_BUF_SIZE, //
|
||||||
|
0, //
|
||||||
|
nullptr); //
|
||||||
|
if (ml->pipe_handle != INVALID_HANDLE_VALUE) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
DWORD err = GetLastError();
|
DWORD err = GetLastError();
|
||||||
if (err == ERROR_PIPE_BUSY) {
|
if (err == ERROR_PIPE_BUSY) {
|
||||||
U_LOG_W("CreateNamedPipeA failed: %d %s An existing client must disconnect first!", err,
|
U_LOG_W("CreateNamedPipeA failed: %d %s An existing client must disconnect first!", err,
|
||||||
ipc_winerror(err));
|
ipc_winerror(err));
|
||||||
} else {
|
} else {
|
||||||
U_LOG_E("CreateNamedPipeA failed: %d %s", err, ipc_winerror(err));
|
U_LOG_E("CreateNamedPipeA failed: %d %s", err, ipc_winerror(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_another_pipe_instance(struct ipc_server *vs, struct ipc_server_mainloop *ml)
|
||||||
|
{
|
||||||
|
if (!create_pipe_instance(ml, false)) {
|
||||||
ipc_server_handle_failure(vs);
|
ipc_server_handle_failure(vs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_connected_client(struct ipc_server *vs, struct ipc_server_mainloop *ml)
|
||||||
|
{
|
||||||
|
DWORD mode = PIPE_READMODE_MESSAGE | PIPE_WAIT;
|
||||||
|
BOOL bRet;
|
||||||
|
|
||||||
|
bRet = SetNamedPipeHandleState(ml->pipe_handle, &mode, nullptr, nullptr);
|
||||||
|
if (bRet) {
|
||||||
|
ipc_server_start_client_listener_thread(vs, ml->pipe_handle);
|
||||||
|
create_another_pipe_instance(vs, ml);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD err = GetLastError();
|
||||||
|
U_LOG_E("SetNamedPipeHandleState(PIPE_READMODE_MESSAGE | PIPE_WAIT) failed: %d %s", err, ipc_winerror(err));
|
||||||
|
ipc_server_handle_failure(vs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Exported functions
|
* Exported functions
|
||||||
|
@ -74,33 +118,22 @@ ipc_server_mainloop_poll(struct ipc_server *vs, struct ipc_server_mainloop *ml)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ml->pipe_handle) {
|
if (!ml->pipe_handle) {
|
||||||
ipc_server_create_another_pipe_instance(vs, ml);
|
create_another_pipe_instance(vs, ml);
|
||||||
}
|
}
|
||||||
if (!ml->pipe_handle) {
|
if (!ml->pipe_handle) {
|
||||||
|
return; // Errors already logged.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConnectNamedPipe(ml->pipe_handle, nullptr)) {
|
||||||
|
DWORD err = GetLastError();
|
||||||
|
U_LOG_E("ConnectNamedPipe unexpected return TRUE treating as failure: %d %s", err, ipc_winerror(err));
|
||||||
|
ipc_server_handle_failure(vs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ConnectNamedPipe(ml->pipe_handle, NULL)) {
|
|
||||||
U_LOG_E("ConnectNamedPipe unexpected return TRUE (last error: %d). Treating as failure...",
|
|
||||||
GetLastError());
|
|
||||||
ipc_server_handle_failure(vs);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (DWORD err = GetLastError()) {
|
switch (DWORD err = GetLastError()) {
|
||||||
case ERROR_PIPE_LISTENING: return;
|
case ERROR_PIPE_LISTENING: return;
|
||||||
case ERROR_PIPE_CONNECTED: {
|
case ERROR_PIPE_CONNECTED: handle_connected_client(vs, ml); return;
|
||||||
DWORD mode = PIPE_READMODE_MESSAGE | PIPE_WAIT;
|
|
||||||
if (!SetNamedPipeHandleState(ml->pipe_handle, &mode, NULL, NULL)) {
|
|
||||||
err = GetLastError();
|
|
||||||
U_LOG_E("SetNamedPipeHandleState(PIPE_READMODE_MESSAGE | PIPE_WAIT) failed: %d %s", err,
|
|
||||||
ipc_winerror(err));
|
|
||||||
ipc_server_handle_failure(vs);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ipc_server_start_client_listener_thread(vs, ml->pipe_handle);
|
|
||||||
ipc_server_create_another_pipe_instance(vs, ml);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
U_LOG_E("ConnectNamedPipe failed: %d %s", err, ipc_winerror(err));
|
U_LOG_E("ConnectNamedPipe failed: %d %s", err, ipc_winerror(err));
|
||||||
ipc_server_handle_failure(vs);
|
ipc_server_handle_failure(vs);
|
||||||
|
@ -127,20 +160,21 @@ ipc_server_mainloop_init(struct ipc_server_mainloop *ml)
|
||||||
}
|
}
|
||||||
|
|
||||||
ml->pipe_name = _strdup(pipe_name);
|
ml->pipe_name = _strdup(pipe_name);
|
||||||
if (!ml->pipe_name) {
|
if (ml->pipe_name == nullptr) {
|
||||||
U_LOG_E("_strdup(\"%s\") failed!", pipe_name);
|
U_LOG_E("_strdup(\"%s\") failed!", pipe_name);
|
||||||
} else {
|
goto err;
|
||||||
ml->pipe_handle = CreateNamedPipeA(ml->pipe_name, PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
|
}
|
||||||
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_NOWAIT |
|
|
||||||
PIPE_REJECT_REMOTE_CLIENTS,
|
if (!create_pipe_instance(ml, true)) {
|
||||||
IPC_MAX_CLIENTS, IPC_BUF_SIZE, IPC_BUF_SIZE, 0, NULL);
|
U_LOG_E("CreateNamedPipeA \"%s\" first instance failed, see above.", ml->pipe_name);
|
||||||
if (ml->pipe_handle != INVALID_HANDLE_VALUE) {
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
DWORD err = GetLastError();
|
err:
|
||||||
U_LOG_E("CreateNamedPipeA \"%s\" first instance failed: %d %s", ml->pipe_name, err, ipc_winerror(err));
|
|
||||||
}
|
|
||||||
ipc_server_mainloop_deinit(ml);
|
ipc_server_mainloop_deinit(ml);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue