1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-26 21:23:21 +00:00

Update to use new threading model for windows

This commit is contained in:
Bryan Roe
2020-05-07 10:29:49 -07:00
parent 47066bd825
commit 9668b8d77d
5 changed files with 226 additions and 680 deletions

View File

@@ -110,39 +110,15 @@ void ILibDuktape_ChildProcess_SubProcess_ExitHandler(ILibProcessPipe_Process sen
ILibDuktape_ChildProcess_SubProcess *p = (ILibDuktape_ChildProcess_SubProcess*)user;
if (!ILibMemory_CanaryOK(p)) { return; }
#ifdef WIN32
if (duk_ctx_context_data(p->ctx)->apc_flags == 0 && p->dispatchFlags == 0)
{
// This method was called with an APC, but this thread was running an unknown alertable method when it was interrupted
// So we must unwind the stack, and use a non-apc method to re-dispatch to this thread, becuase we can't risk
// calling a winsock method, in case this thread was inside winsock when it was interrupted, because otherwise, it
// will corrupt memory, resulting in a possible crash.
//
// We had to do the APC first, becuase otherwise child_process.waitExit() will not work, becuase that method is blocking
// the event loop thread with an alertable wait object, so APC is the only way to propagate this event
p->exitCode = exitCode;
p->dispatchFlags = 1;
Duktape_RunOnEventLoop(p->chain, duk_ctx_nonce(p->ctx), p->ctx, ILibDuktape_ChildProcess_SubProcess_ExitHandler_sink1, NULL, p);
return;
}
#endif
p->exitCode = exitCode;
p->childProcess = NULL;
duk_push_heapptr(p->ctx, p->subProcess); // [childProcess]
#ifdef WIN32
HANDLE exitptr = (HANDLE)Duktape_GetPointerProperty(p->ctx, -1, "\xFF_WaitExit");
if (exitptr != NULL)
{
SetEvent(exitptr);
}
#else
if (Duktape_GetIntPropertyValue(p->ctx, -1, "\xFF_WaitExit", 0) != 0)
{
ILibChain_EndContinue(Duktape_GetChain(p->ctx));
}
#endif
duk_get_prop_string(p->ctx, -1, "emit"); // [childProcess][emit]
duk_swap_top(p->ctx, -2); // [emit][this]
duk_push_string(p->ctx, "exit"); // [emit][this][exit]
@@ -198,25 +174,11 @@ duk_ret_t ILibDuktape_ChildProcess_waitExit(duk_context *ctx)
return(ILibDuktape_Error(ctx, "Cannot waitExit() because JS Engine is exiting"));
}
#ifdef WIN32
DWORD result;
HANDLE eptr = CreateEventA(NULL, TRUE, FALSE, NULL);
duk_push_pointer(ctx, (void*)eptr);
#else
duk_push_int(ctx, 1); // [spawnedProcess][flag]
#endif
duk_put_prop_string(ctx, -2, "\xFF_WaitExit"); // [spawnedProcess]
#ifdef WIN32
duk_ctx_context_data(ctx)->apc_flags = 1;
while ((result=WaitForSingleObjectEx(eptr, duk_is_number(ctx, 0) ? duk_require_int(ctx, 0) : INFINITE, TRUE)) != WAIT_OBJECT_0 && result != WAIT_TIMEOUT);
duk_ctx_context_data(ctx)->apc_flags = 0;
CloseHandle(eptr);
if (result == WAIT_TIMEOUT) { return(ILibDuktape_Error(ctx, "timeout")); }
#else
void *mods[] = { ILibGetBaseTimer(Duktape_GetChain(ctx)), Duktape_GetPointerProperty(ctx, -1, ILibDuktape_ChildProcess_Manager) };
ILibChain_Continue(chain, (ILibChain_Link**)mods, 2, -1);
#endif
return(0);
}

View File

@@ -867,7 +867,6 @@ void ILibDuktape_net_server_IPC_readsink(ILibProcessPipe_Pipe sender, void *user
// Server IPC, so we can create a new Instance, and listen for a connection
duk_context *ctx = winIPC->ctx; // We need to dereference this, because winIPC will go out of scope when we call listen
CloseHandle(winIPC->overlapped.hEvent); winIPC->overlapped.hEvent = NULL;
if (winIPC->buffer != NULL) { free(winIPC->buffer); winIPC->buffer = NULL; }
duk_push_heapptr(winIPC->ctx, winIPC->mSocket); // [connection]
duk_del_prop_string(ctx, -1, ILibDuktape_net_WindowsIPC_Buffer); duk_pop(winIPC->ctx); // ...
@@ -1055,7 +1054,6 @@ duk_ret_t ILibDuktape_net_server_IPC_ConnectSink_Finalizer(duk_context *ctx)
ILibProcessPipe_FreePipe(winIPC->mPipe);
winIPC->mPipe = NULL; winIPC->mPipeHandle = NULL;
}
if (winIPC->buffer != NULL) { free(winIPC->buffer); winIPC->buffer = NULL; }
}
return(0);
}
@@ -1317,7 +1315,7 @@ duk_ret_t ILibDuktape_net_server_Finalizer(duk_context *ctx)
ILibDuktape_net_WindowsIPC *ipc = Duktape_GetBufferProperty(ctx, 0, ILibDuktape_net_WindowsIPC_Buffer);
if (ipc != NULL && ipc->overlapped.hEvent != NULL)
{
ILibProcessPipe_WaitHandle_Remove(ipc->manager, ipc->overlapped.hEvent);
ILibChain_RemoveWaitHandle(duk_ctx_chain(ctx), ipc->overlapped.hEvent);
if (ipc->mPipeHandle != NULL) { CloseHandle(ipc->mPipeHandle); ipc->mPipeHandle = NULL; }
if (ipc->overlapped.hEvent != NULL) { CloseHandle(ipc->overlapped.hEvent); ipc->overlapped.hEvent = NULL; }
}