mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-11 13:53:37 +00:00
1. Fixed process HANDLE leak on windows
2. Replaced semaphore with spinlock on event emitter object.
This commit is contained in:
@@ -37,7 +37,7 @@ typedef struct ILibDuktape_EventEmitter
|
|||||||
unsigned int *totalListeners;
|
unsigned int *totalListeners;
|
||||||
const char *listenerCountTable;
|
const char *listenerCountTable;
|
||||||
size_t listenerCountTableLength;
|
size_t listenerCountTableLength;
|
||||||
sem_t listenerCountTableLock;
|
ILibSpinLock listenerCountTableLock;
|
||||||
ILibDuktape_EventEmitter_Types eventType;
|
ILibDuktape_EventEmitter_Types eventType;
|
||||||
}ILibDuktape_EventEmitter;
|
}ILibDuktape_EventEmitter;
|
||||||
typedef void(*ILibDuktape_EventEmitter_HookHandler)(ILibDuktape_EventEmitter *sender, char *eventName, void *hookedCallback);
|
typedef void(*ILibDuktape_EventEmitter_HookHandler)(ILibDuktape_EventEmitter *sender, char *eventName, void *hookedCallback);
|
||||||
|
|||||||
@@ -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));
|
duk_push_boolean(ctx, (duk_bool_t)duk_ctx_shutting_down(ctx));
|
||||||
return(1);
|
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)
|
void ILibDuktape_ScriptContainer_Process_Init(duk_context *ctx, char **argList)
|
||||||
{
|
{
|
||||||
int i = 0;
|
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_CreateEventWithGetter(ctx, "env", ILibDuktape_ScriptContainer_Process_env);
|
||||||
ILibDuktape_CreateInstanceMethod(ctx, "cwd", ILibDuktape_Process_cwd, 0);
|
ILibDuktape_CreateInstanceMethod(ctx, "cwd", ILibDuktape_Process_cwd, 0);
|
||||||
ILibDuktape_CreateInstanceMethod(ctx, "setenv", ILibDuktape_Process_setenv, 2);
|
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);
|
ILibDuktape_CreateEventWithGetterAndSetterEx(ctx, "coreDumpLocation", ILibDuktape_ScriptContainer_Process_coreDumpLocation_getter, ILibDuktape_ScriptContainer_Process_coreDumpLocation_setter);
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
ILibDuktape_CreateEventWithGetter(ctx, "rlimit", ILibDuktape_ScriptContainer_Process_rlimit_getter);
|
ILibDuktape_CreateEventWithGetter(ctx, "rlimit", ILibDuktape_ScriptContainer_Process_rlimit_getter);
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ int ILibDuktape_EventEmitter_HasListeners2(ILibDuktape_EventEmitter *emitter, ch
|
|||||||
int retVal = defaultValue;
|
int retVal = defaultValue;
|
||||||
if (emitter != NULL && ILibMemory_CanaryOK(emitter) && duk_ctx_is_alive(emitter->ctx))
|
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)
|
if (emitter->listenerCountTableLength > 2 && emitter->listenerCountTableLength < INT32_MAX)
|
||||||
{
|
{
|
||||||
size_t eventNameLen = strnlen_s(eventName, ILibDuktape_EventEmitter_MaxEventNameLen);
|
size_t eventNameLen = strnlen_s(eventName, ILibDuktape_EventEmitter_MaxEventNameLen);
|
||||||
@@ -169,7 +169,7 @@ int ILibDuktape_EventEmitter_HasListeners2(ILibDuktape_EventEmitter *emitter, ch
|
|||||||
}
|
}
|
||||||
ILibDestructParserResults(pr);
|
ILibDestructParserResults(pr);
|
||||||
}
|
}
|
||||||
sem_post(&(emitter->listenerCountTableLock));
|
ILibSpinLock_UnLock(&(emitter->listenerCountTableLock));
|
||||||
}
|
}
|
||||||
return(retVal);
|
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);
|
ILibDuktape_Process_UncaughtExceptionEx(ctx, "Error in Finalizer (%s): [Invalid C function means you forgot to return 0] ", meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
sem_destroy(&(data->listenerCountTableLock));
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
duk_ret_t ILibDuktape_EventEmitter_emitReturnValue(duk_context *ctx)
|
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);
|
duk_push_this(ctx);
|
||||||
ILibDuktape_EventEmitter *emitter = (ILibDuktape_EventEmitter*)Duktape_GetBufferProperty(ctx, -1, ILibDuktape_EventEmitter_Data);
|
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_push_global_object(ctx); // [g]
|
||||||
duk_get_prop_string(ctx, -1, "JSON"); // [g][JSON]
|
duk_get_prop_string(ctx, -1, "JSON"); // [g][JSON]
|
||||||
duk_prepare_method_call(ctx, -1, "parse"); // [g][JSON][parse][this]
|
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);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -738,7 +737,7 @@ ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx)
|
|||||||
duk_push_object(ctx);
|
duk_push_object(ctx);
|
||||||
retVal->retValTable = duk_get_heapptr(ctx, -1);
|
retVal->retValTable = duk_get_heapptr(ctx, -1);
|
||||||
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_LastRetValueTable);
|
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_LastRetValueTable);
|
||||||
sem_init(&(retVal->listenerCountTableLock), 0, 1);
|
ILibSpinLock_Init(&(retVal->listenerCountTableLock));
|
||||||
retVal->listenerCountTable = (char*)"[]";
|
retVal->listenerCountTable = (char*)"[]";
|
||||||
retVal->listenerCountTableLength = 2;
|
retVal->listenerCountTableLength = 2;
|
||||||
|
|
||||||
|
|||||||
@@ -131,6 +131,9 @@ char ILibScratchPad[4096]; // General buffer
|
|||||||
char ILibScratchPad2[65536]; // Often used for UDP packet processing
|
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
|
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
|
#define ILibChain_SIGMAX 32
|
||||||
ILibLinkedList g_signalHandlers[ILibChain_SIGMAX] = { NULL };
|
ILibLinkedList g_signalHandlers[ILibChain_SIGMAX] = { NULL };
|
||||||
typedef struct ILibChain_SignalHandlerData
|
typedef struct ILibChain_SignalHandlerData
|
||||||
|
|||||||
@@ -112,6 +112,32 @@ struct sockaddr_in6;
|
|||||||
#include <winbase.h>
|
#include <winbase.h>
|
||||||
#endif
|
#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
|
#ifdef WIN32
|
||||||
#define ILIB_CURRENT_THREAD (unsigned int)GetCurrentThreadId()
|
#define ILIB_CURRENT_THREAD (unsigned int)GetCurrentThreadId()
|
||||||
#else
|
#else
|
||||||
@@ -170,6 +196,9 @@ static inline void ignore_result(uintptr_t result) { (void)result; }
|
|||||||
#define PRINTERROR()
|
#define PRINTERROR()
|
||||||
#endif
|
#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_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);
|
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.
|
// Implemented in Windows using events.
|
||||||
#define sem_t HANDLE
|
#define sem_t HANDLE
|
||||||
#define sem_init(x,pShared,InitValue) *x=CreateSemaphore(NULL,InitValue,SEM_MAX_COUNT,NULL)
|
#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)
|
#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_wait(x) WaitForSingleObject(*x,INFINITE)
|
||||||
#define sem_trywait(x) ((WaitForSingleObject(*x,0)==WAIT_OBJECT_0)?0:1)
|
#define sem_trywait(x) ((WaitForSingleObject(*x,0)==WAIT_OBJECT_0)?0:1)
|
||||||
#define sem_post(x) ReleaseSemaphore(*x,1,NULL)
|
#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 strncasecmp(x,y,z) _strnicmp(x,y,z)
|
||||||
#define strcasecmp(x,y) _stricmp(x,y)
|
#define strcasecmp(x,y) _stricmp(x,y)
|
||||||
#define gettimeofday(tp,tzp) ILibGetTimeOfDay(tp)
|
#define gettimeofday(tp,tzp) ILibGetTimeOfDay(tp)
|
||||||
|
|||||||
@@ -451,6 +451,9 @@ void ILibProcessPipe_Process_Destroy(ILibProcessPipe_Process_Object *p)
|
|||||||
if (p->stdOut != NULL) { ILibProcessPipe_FreePipe(p->stdOut); }
|
if (p->stdOut != NULL) { ILibProcessPipe_FreePipe(p->stdOut); }
|
||||||
if (p->stdErr != NULL) { ILibProcessPipe_FreePipe(p->stdErr); }
|
if (p->stdErr != NULL) { ILibProcessPipe_FreePipe(p->stdErr); }
|
||||||
if (p->metadata != NULL) { ILibMemory_Free(p->metadata); }
|
if (p->metadata != NULL) { ILibMemory_Free(p->metadata); }
|
||||||
|
#ifdef WIN32
|
||||||
|
if (p->hProcess != NULL) { CloseHandle(p->hProcess); }
|
||||||
|
#endif
|
||||||
ILibMemory_Free(p);
|
ILibMemory_Free(p);
|
||||||
}
|
}
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
|
|||||||
Reference in New Issue
Block a user