mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-15 15:53:55 +00:00
Added ability to Save/Restore handle wait state
Fixed edge case that could cause a connection to resume twice
This commit is contained in:
@@ -701,6 +701,8 @@ duk_ret_t ILibDuktape_readableStream_pipe(duk_context *ctx)
|
|||||||
duk_call_method(ctx, 2); duk_pop(ctx); // ...
|
duk_call_method(ctx, 2); duk_pop(ctx); // ...
|
||||||
if (rstream->paused != 0)
|
if (rstream->paused != 0)
|
||||||
{
|
{
|
||||||
|
rstream->paused = 0; // Set state now, so nobody tries to resume before we can finish piping
|
||||||
|
|
||||||
// We are paused, so we should yield and resume... We yield, so in case the user tries to chain multiple pipes, it will chain first
|
// We are paused, so we should yield and resume... We yield, so in case the user tries to chain multiple pipes, it will chain first
|
||||||
rstream->resumeImmediate = ILibDuktape_Immediate(ctx, (void*[]) { rstream, duk_get_heapptr(ctx, 0) }, 1, ILibDuktape_ReadableStream_pipe_ResumeLater);
|
rstream->resumeImmediate = ILibDuktape_Immediate(ctx, (void*[]) { rstream, duk_get_heapptr(ctx, 0) }, 1, ILibDuktape_ReadableStream_pipe_ResumeLater);
|
||||||
duk_push_heapptr(ctx, rstream->resumeImmediate); // [immediate]
|
duk_push_heapptr(ctx, rstream->resumeImmediate); // [immediate]
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ typedef struct ILibDuktape_net_WindowsIPC
|
|||||||
OVERLAPPED overlapped;
|
OVERLAPPED overlapped;
|
||||||
ILibDuktape_DuplexStream *ds;
|
ILibDuktape_DuplexStream *ds;
|
||||||
BOOL clientConnected;
|
BOOL clientConnected;
|
||||||
|
void *reservedState;
|
||||||
ULONG_PTR _reserved[5];
|
ULONG_PTR _reserved[5];
|
||||||
|
|
||||||
char *buffer;
|
char *buffer;
|
||||||
@@ -947,12 +947,22 @@ void ILibDuktape_net_server_IPC_PauseSink(ILibDuktape_DuplexStream *sender, void
|
|||||||
// No-OP, becuase all we need to so is set Paused flag, which is already the case when we get here
|
// No-OP, becuase all we need to so is set Paused flag, which is already the case when we get here
|
||||||
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
|
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
|
||||||
winIPC->paused = 1;
|
winIPC->paused = 1;
|
||||||
|
|
||||||
|
winIPC->reservedState = ILibChain_WaitHandle_RemoveAndSaveState(winIPC->mChain, winIPC->read_overlapped.hEvent);
|
||||||
}
|
}
|
||||||
void ILibDuktape_net_server_IPC_ResumeSink(ILibDuktape_DuplexStream *sender, void *user)
|
void ILibDuktape_net_server_IPC_ResumeSink(ILibDuktape_DuplexStream *sender, void *user)
|
||||||
{
|
{
|
||||||
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
|
ILibDuktape_net_WindowsIPC *winIPC = (ILibDuktape_net_WindowsIPC*)user;
|
||||||
winIPC->paused = 0;
|
winIPC->paused = 0;
|
||||||
ILibDuktape_server_ipc_ReadSink(winIPC->mChain, winIPC->mPipeHandle, ILibWaitHandle_ErrorStatus_NONE, NULL, 0, winIPC);
|
if (winIPC->reservedState != NULL)
|
||||||
|
{
|
||||||
|
ILibChain_WaitHandle_RestoreState(winIPC->mChain, winIPC->reservedState);
|
||||||
|
winIPC->reservedState = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ILibDuktape_server_ipc_ReadSink(winIPC->mChain, winIPC->mPipeHandle, ILibWaitHandle_ErrorStatus_NONE, NULL, 0, winIPC);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ILibTransport_DoneState ILibDuktape_net_server_IPC_WriteSink(ILibDuktape_DuplexStream *stream, char *buffer, int bufferLen, void *user)
|
ILibTransport_DoneState ILibDuktape_net_server_IPC_WriteSink(ILibDuktape_DuplexStream *stream, char *buffer, int bufferLen, void *user)
|
||||||
|
|||||||
@@ -3274,7 +3274,55 @@ void ILibChain_ReadEx2(void *chain, HANDLE h, OVERLAPPED *p, char *buffer, int b
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOL ILibChain_WaitHandleAdded(void *chain, HANDLE h)
|
||||||
|
{
|
||||||
|
return(ILibLinkedList_GetNode_Search(((ILibBaseChain*)chain)->auxSelectHandles, NULL, h) != NULL);
|
||||||
|
}
|
||||||
|
void* ILibChain_WaitHandle_RemoveAndSaveState(void *chain, HANDLE h)
|
||||||
|
{
|
||||||
|
ILibChain_WaitHandleInfo *ret = NULL;
|
||||||
|
void *node = ILibLinkedList_GetNode_Search(((ILibBaseChain*)chain)->auxSelectHandles, NULL, h);
|
||||||
|
if (node != NULL)
|
||||||
|
{
|
||||||
|
ret = (ILibChain_WaitHandleInfo*)ILibMemory_SmartAllocate(sizeof(ILibChain_WaitHandleInfo));
|
||||||
|
memcpy_s(ret, ILibMemory_Size(ret), ILibMemory_Extra(node), ILibMemory_Size(ret));
|
||||||
|
ret->node = h;
|
||||||
|
ILibLinkedList_Remove(node);
|
||||||
|
|
||||||
|
if (((ILibBaseChain*)chain)->currentHandle == h)
|
||||||
|
{
|
||||||
|
((ILibBaseChain*)chain)->currentHandle = NULL; ((ILibBaseChain*)chain)->currentInfo = NULL;
|
||||||
|
}
|
||||||
|
((ILibBaseChain*)chain)->UnblockFlag = 1;
|
||||||
|
}
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
void ILibChain_WaitHandle_RestoreState(void *chain, void *state)
|
||||||
|
{
|
||||||
|
ILibChain_WaitHandleInfo *info = (ILibChain_WaitHandleInfo*)state;
|
||||||
|
int msTIMEOUT = -1;
|
||||||
|
struct timeval current;
|
||||||
|
|
||||||
|
if (tvnonzero(&(info->expiration)))
|
||||||
|
{
|
||||||
|
// Expiration was specified
|
||||||
|
ILibGetTimeOfDay(¤t);
|
||||||
|
|
||||||
|
if (tv2LTEtv1(&(info->expiration), ¤t))
|
||||||
|
{
|
||||||
|
// Expiration happened in the past
|
||||||
|
msTIMEOUT = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Expiration is in the future
|
||||||
|
msTIMEOUT = ILibGetMillisecondTimeSpan(&(info->expiration), ¤t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ILibChain_AddWaitHandleEx(chain, info->node, msTIMEOUT, info->handler, info->user, info->metadata);
|
||||||
|
ILibMemory_Free(info);
|
||||||
|
}
|
||||||
void __stdcall ILibChain_AddWaitHandle_apc(ULONG_PTR u)
|
void __stdcall ILibChain_AddWaitHandle_apc(ULONG_PTR u)
|
||||||
{
|
{
|
||||||
void *chain = ((void**)u)[0];
|
void *chain = ((void**)u)[0];
|
||||||
@@ -8782,6 +8830,42 @@ void ILibGetDiskFreeSpace(void *i64FreeBytesToCaller, void *i64TotalBytes)
|
|||||||
*((uint64_t *)i64TotalBytes)= (uint64_t)stfs.f_blocks * stfs.f_bsize;
|
*((uint64_t *)i64TotalBytes)= (uint64_t)stfs.f_blocks * stfs.f_bsize;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ILibGetMillisecondTimeSpan(struct timeval *tv1, struct timeval *tv2)
|
||||||
|
{
|
||||||
|
struct timeval a;
|
||||||
|
struct timeval b;
|
||||||
|
int seconds;
|
||||||
|
|
||||||
|
if (tv2LTtv1(tv1, tv2))
|
||||||
|
{
|
||||||
|
memcpy_s(&a, sizeof(a), tv2, sizeof(a));
|
||||||
|
memcpy_s(&b, sizeof(b), tv1, sizeof(b));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy_s(&b, sizeof(b), tv2, sizeof(b));
|
||||||
|
memcpy_s(&a, sizeof(a), tv1, sizeof(a));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.tv_usec < a.tv_usec)
|
||||||
|
{
|
||||||
|
seconds = (a.tv_usec - b.tv_usec) / 1000000 + 1;
|
||||||
|
a.tv_usec -= (1000000 * seconds);
|
||||||
|
a.tv_sec += seconds;
|
||||||
|
}
|
||||||
|
if (b.tv_usec - a.tv_usec > 1000000)
|
||||||
|
{
|
||||||
|
seconds = (b.tv_usec - a.tv_usec) / 1000000;
|
||||||
|
a.tv_usec += (1000000 * seconds);
|
||||||
|
a.tv_sec -= seconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Millisecond Span
|
||||||
|
return(((b.tv_sec - a.tv_sec) * 1000) + ((b.tv_usec - a.tv_usec) / 1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
long ILibGetTimeStamp()
|
long ILibGetTimeStamp()
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|||||||
@@ -999,6 +999,10 @@ int ILibIsRunningOnChainThread(void* chain);
|
|||||||
}ILibChain_WriteEx_data;
|
}ILibChain_WriteEx_data;
|
||||||
|
|
||||||
char *ILibChain_MetaData(char *file, int number);
|
char *ILibChain_MetaData(char *file, int number);
|
||||||
|
int ILibGetMillisecondTimeSpan(struct timeval *tv1, struct timeval *tv2);
|
||||||
|
void* ILibChain_WaitHandle_RemoveAndSaveState(void *chain, HANDLE h);
|
||||||
|
void ILibChain_WaitHandle_RestoreState(void *chain, void *state);
|
||||||
|
BOOL ILibChain_WaitHandleAdded(void *chain, HANDLE h);
|
||||||
void ILibChain_AddWaitHandleEx(void *chain, HANDLE h, int msTIMEOUT, ILibChain_WaitHandleHandler handler, void *user, char *metadata);
|
void ILibChain_AddWaitHandleEx(void *chain, HANDLE h, int msTIMEOUT, ILibChain_WaitHandleHandler handler, void *user, char *metadata);
|
||||||
#define ILibChain_AddWaitHandle(chain, h, msTIMEOUT, handler, user) ILibChain_AddWaitHandleEx(chain, h, msTIMEOUT, handler, user, ILibChain_MetaData(__FILE__, __LINE__))
|
#define ILibChain_AddWaitHandle(chain, h, msTIMEOUT, handler, user) ILibChain_AddWaitHandleEx(chain, h, msTIMEOUT, handler, user, ILibChain_MetaData(__FILE__, __LINE__))
|
||||||
void ILibChain_RemoveWaitHandle(void *chain, HANDLE h);
|
void ILibChain_RemoveWaitHandle(void *chain, HANDLE h);
|
||||||
|
|||||||
Reference in New Issue
Block a user