1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-06 00:13:33 +00:00

1. Fixed process HANDLE leak on windows

2. Replaced semaphore with spinlock on event emitter object.
This commit is contained in:
Bryan Roe
2020-11-26 11:30:23 -08:00
parent bb71feabbf
commit 77834337fd
6 changed files with 85 additions and 18 deletions

View File

@@ -37,7 +37,7 @@ typedef struct ILibDuktape_EventEmitter
unsigned int *totalListeners;
const char *listenerCountTable;
size_t listenerCountTableLength;
sem_t listenerCountTableLock;
ILibSpinLock listenerCountTableLock;
ILibDuktape_EventEmitter_Types eventType;
}ILibDuktape_EventEmitter;
typedef void(*ILibDuktape_EventEmitter_HookHandler)(ILibDuktape_EventEmitter *sender, char *eventName, void *hookedCallback);

View File

@@ -1167,7 +1167,48 @@ duk_ret_t ILibDuktape_Process_Exitting(duk_context *ctx)
duk_push_boolean(ctx, (duk_bool_t)duk_ctx_shutting_down(ctx));
return(1);
}
void ILibDuktape_Process_SemaphoreTracking_sink(char *source, void *user, int init)
{
duk_context *ctx = user;
if (ctx != NULL && duk_ctx_is_alive(ctx) != 0 && duk_ctx_shutting_down(ctx) == 0)
{
duk_push_heap_stash(ctx); // [stash]
int v = Duktape_GetIntPropertyValue(ctx, -1, "_SemTrack", 0);
duk_push_int(ctx, init ? (++v) : (--v)); // [stash][int]
duk_put_prop_string(ctx, -2, "_SemTrack"); // [stash]
duk_pop(ctx); // ...
duk_push_global_object(ctx); // [g]
duk_get_prop_string(ctx, -1, "console"); // [g][console]
duk_prepare_method_call(ctx, -1, "log"); // [g][console][log][this]
duk_push_sprintf(ctx, "[%d] Semaphore <<%s>> (%s)", v, source, init ? "INIT" : "DESTROY"); // [g][console][log][this][string]
duk_pcall_method(ctx, 1); // [g][console][val]
duk_pop_3(ctx); // ...
}
else
{
ILibSemaphoreTrack_user = NULL;
ILibSemaphoreTrack_func = NULL;
}
}
duk_ret_t ILibDuktape_Process_SemaphoreTracking(duk_context *ctx)
{
if (duk_require_boolean(ctx, 0) != 0)
{
duk_push_heap_stash(ctx); // [stash]
duk_push_int(ctx, 0); // [stash][int]
duk_put_prop_string(ctx, -2, "_SemTrack"); // [stash]
duk_pop(ctx); // ...
ILibSemaphoreTrack_user = ctx;
ILibSemaphoreTrack_func = ILibDuktape_Process_SemaphoreTracking_sink;
}
else
{
ILibSemaphoreTrack_user = NULL;
ILibSemaphoreTrack_func = NULL;
}
return(0);
}
void ILibDuktape_ScriptContainer_Process_Init(duk_context *ctx, char **argList)
{
int i = 0;
@@ -1183,6 +1224,7 @@ void ILibDuktape_ScriptContainer_Process_Init(duk_context *ctx, char **argList)
ILibDuktape_CreateEventWithGetter(ctx, "env", ILibDuktape_ScriptContainer_Process_env);
ILibDuktape_CreateInstanceMethod(ctx, "cwd", ILibDuktape_Process_cwd, 0);
ILibDuktape_CreateInstanceMethod(ctx, "setenv", ILibDuktape_Process_setenv, 2);
ILibDuktape_CreateEventWithSetterEx(ctx, "_SemaphoreTracking", ILibDuktape_Process_SemaphoreTracking);
ILibDuktape_CreateEventWithGetterAndSetterEx(ctx, "coreDumpLocation", ILibDuktape_ScriptContainer_Process_coreDumpLocation_getter, ILibDuktape_ScriptContainer_Process_coreDumpLocation_setter);
#ifndef WIN32
ILibDuktape_CreateEventWithGetter(ctx, "rlimit", ILibDuktape_ScriptContainer_Process_rlimit_getter);

View File

@@ -133,7 +133,7 @@ int ILibDuktape_EventEmitter_HasListeners2(ILibDuktape_EventEmitter *emitter, ch
int retVal = defaultValue;
if (emitter != NULL && ILibMemory_CanaryOK(emitter) && duk_ctx_is_alive(emitter->ctx))
{
sem_wait(&(emitter->listenerCountTableLock));
ILibSpinLock_Lock(&(emitter->listenerCountTableLock));
if (emitter->listenerCountTableLength > 2 && emitter->listenerCountTableLength < INT32_MAX)
{
size_t eventNameLen = strnlen_s(eventName, ILibDuktape_EventEmitter_MaxEventNameLen);
@@ -169,7 +169,7 @@ int ILibDuktape_EventEmitter_HasListeners2(ILibDuktape_EventEmitter *emitter, ch
}
ILibDestructParserResults(pr);
}
sem_post(&(emitter->listenerCountTableLock));
ILibSpinLock_UnLock(&(emitter->listenerCountTableLock));
}
return(retVal);
}
@@ -541,7 +541,6 @@ duk_ret_t ILibDuktape_EventEmitter_EmbeddedFinalizer(duk_context *ctx)
ILibDuktape_Process_UncaughtExceptionEx(ctx, "Error in Finalizer (%s): [Invalid C function means you forgot to return 0] ", meta);
}
sem_destroy(&(data->listenerCountTableLock));
return(0);
}
duk_ret_t ILibDuktape_EventEmitter_emitReturnValue(duk_context *ctx)
@@ -653,7 +652,7 @@ duk_ret_t ILibDuktape_EventEmitter_listeners_tableinit(duk_context *ctx)
duk_push_this(ctx);
ILibDuktape_EventEmitter *emitter = (ILibDuktape_EventEmitter*)Duktape_GetBufferProperty(ctx, -1, ILibDuktape_EventEmitter_Data);
sem_wait(&(emitter->listenerCountTableLock));
ILibSpinLock_Lock(&(emitter->listenerCountTableLock));
duk_push_global_object(ctx); // [g]
duk_get_prop_string(ctx, -1, "JSON"); // [g][JSON]
duk_prepare_method_call(ctx, -1, "parse"); // [g][JSON][parse][this]
@@ -712,7 +711,7 @@ duk_ret_t ILibDuktape_EventEmitter_listeners_tableinit(duk_context *ctx)
}
}
}
sem_post(&(emitter->listenerCountTableLock));
ILibSpinLock_UnLock(&(emitter->listenerCountTableLock));
return(0);
}
@@ -738,7 +737,7 @@ ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx)
duk_push_object(ctx);
retVal->retValTable = duk_get_heapptr(ctx, -1);
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_LastRetValueTable);
sem_init(&(retVal->listenerCountTableLock), 0, 1);
ILibSpinLock_Init(&(retVal->listenerCountTableLock));
retVal->listenerCountTable = (char*)"[]";
retVal->listenerCountTableLength = 2;

View File

@@ -131,6 +131,9 @@ char ILibScratchPad[4096]; // General buffer
char ILibScratchPad2[65536]; // Often used for UDP packet processing
void* gILibChain = NULL; // Global Chain Instance used for Remote Logging when a chain instance isn't otherwise exposed
ILibSemaphoreTrack_Handler ILibSemaphoreTrack_func = NULL;
void* ILibSemaphoreTrack_user = NULL;
#define ILibChain_SIGMAX 32
ILibLinkedList g_signalHandlers[ILibChain_SIGMAX] = { NULL };
typedef struct ILibChain_SignalHandlerData

View File

@@ -112,6 +112,32 @@ struct sockaddr_in6;
#include <winbase.h>
#endif
#ifndef WIN32
#include <sched.h>
#endif
#ifdef WIN32
typedef volatile long ILibSpinLock;
#else
typedef volatile int ILibSpinLock;
#endif
static inline void ILibSpinLock_Init(ILibSpinLock *lock) { *lock = 0; }
static inline void ILibSpinLock_UnLock(ILibSpinLock *lock) { *lock = 0; }
static inline void ILibSpinLock_Lock(ILibSpinLock *lock)
{
#ifdef WIN32
while (!InterlockedCompareExchange(lock, 1, 0))
{
YieldProcessor();
}
#else
while (!__sync_bool_compare_and_swap(lock, 0, 1))
{
sched_yield();
}
#endif
}
#ifdef WIN32
#define ILIB_CURRENT_THREAD (unsigned int)GetCurrentThreadId()
#else
@@ -170,6 +196,9 @@ static inline void ignore_result(uintptr_t result) { (void)result; }
#define PRINTERROR()
#endif
typedef void(*ILibSemaphoreTrack_Handler)(char *source, void *user, int init);
extern ILibSemaphoreTrack_Handler ILibSemaphoreTrack_func;
extern void* ILibSemaphoreTrack_user;
int ILib_atoi_uint64_ex(uint64_t *val, const char *instr, size_t instrLen, uint64_t MAX);
int ILib_atoi_uint32_ex(uint32_t *val, const char *instr, size_t instrLen, uint64_t MAX);
@@ -238,21 +267,12 @@ long ILibGetTimeStamp();
// Implemented in Windows using events.
#define sem_t HANDLE
#define sem_init(x,pShared,InitValue) *x=CreateSemaphore(NULL,InitValue,SEM_MAX_COUNT,NULL)
#define sem_destroy(x) (CloseHandle(*x)==0?1:0)
#define sem_init(x,pShared,InitValue) *x=CreateSemaphore(NULL,InitValue,SEM_MAX_COUNT,NULL);if(ILibSemaphoreTrack_func!=NULL){char tmp[512];sprintf_s(tmp, sizeof(tmp), "(%p) %s:%d",(void*)(x),__FILE__,__LINE__);ILibSemaphoreTrack_func(tmp,ILibSemaphoreTrack_user,1);}
#define sem_destroy(x) (CloseHandle(*x)==0?1:0);if(ILibSemaphoreTrack_func!=NULL){char tmp[512];sprintf_s(tmp, sizeof(tmp), "(%p) %s:%d",(void*)(x),__FILE__,__LINE__);ILibSemaphoreTrack_func(tmp,ILibSemaphoreTrack_user,0);}
#define sem_wait(x) WaitForSingleObject(*x,INFINITE)
#define sem_trywait(x) ((WaitForSingleObject(*x,0)==WAIT_OBJECT_0)?0:1)
#define sem_post(x) ReleaseSemaphore(*x,1,NULL)
//// Implemented in Windows using critical section.
//#define sem_t CRITICAL_SECTION
//#define sem_init(x,pShared,InitValue) InitializeCriticalSection(x);
//#define sem_destroy(x) (DeleteCriticalSection(x))
//#define sem_wait(x) EnterCriticalSection(x)
//#define sem_trywait(x) TryEnterCriticalSection(x)
//#define sem_post(x) LeaveCriticalSection(x)
#define strncasecmp(x,y,z) _strnicmp(x,y,z)
#define strcasecmp(x,y) _stricmp(x,y)
#define gettimeofday(tp,tzp) ILibGetTimeOfDay(tp)

View File

@@ -451,6 +451,9 @@ void ILibProcessPipe_Process_Destroy(ILibProcessPipe_Process_Object *p)
if (p->stdOut != NULL) { ILibProcessPipe_FreePipe(p->stdOut); }
if (p->stdErr != NULL) { ILibProcessPipe_FreePipe(p->stdErr); }
if (p->metadata != NULL) { ILibMemory_Free(p->metadata); }
#ifdef WIN32
if (p->hProcess != NULL) { CloseHandle(p->hProcess); }
#endif
ILibMemory_Free(p);
}
#ifndef WIN32