diff --git a/microscript/ILibDuktape_Polyfills.c b/microscript/ILibDuktape_Polyfills.c index 2097cb3..c7225cd 100644 --- a/microscript/ILibDuktape_Polyfills.c +++ b/microscript/ILibDuktape_Polyfills.c @@ -2518,6 +2518,51 @@ duk_ret_t ILibDuktape_DescriptorEvents_Finalizer(duk_context *ctx) return(0); } + +#ifndef WIN32 +void ILibDuktape_DescriptorEvents_GetCount_results_final(void *chain, void *user) +{ + duk_context *ctx = (duk_context*)((void**)user)[0]; + void *hptr = ((void**)user)[1]; + duk_push_heapptr(ctx, hptr); // [promise] + duk_get_prop_string(ctx, -1, "_RES"); // [promise][res] + duk_swap_top(ctx, -2); // [res][this] + duk_push_int(ctx, ILibChain_GetDescriptorCount(duk_ctx_chain(ctx))); // [res][this][count] + duk_pcall_method(ctx, 1); duk_pop(ctx); // ... + free(user); +} +void ILibDuktape_DescriptorEvents_GetCount_results(void *chain, void *user) +{ + ILibChain_RunOnMicrostackThreadEx2(chain, ILibDuktape_DescriptorEvents_GetCount_results_final, user, 1); +} +#endif +duk_ret_t ILibDuktape_DescriptorEvents_GetCount_promise(duk_context *ctx) +{ + duk_push_this(ctx); // [promise] + duk_dup(ctx, 0); duk_put_prop_string(ctx, -2, "_RES"); + duk_dup(ctx, 1); duk_put_prop_string(ctx, -2, "_REJ"); + return(0); +} +duk_ret_t ILibDuktape_DescriptorEvents_GetCount(duk_context *ctx) +{ + duk_eval_string(ctx, "require('promise');"); // [promise] + duk_push_c_function(ctx, ILibDuktape_DescriptorEvents_GetCount_promise, 2); // [promise][func] + duk_new(ctx, 1); // [promise] + +#ifdef WIN32 + duk_get_prop_string(ctx, -1, "_RES"); // [promise][res] + duk_dup(ctx, -2); // [promise][res][this] + duk_push_int(ctx, ILibChain_GetDescriptorCount(duk_ctx_chain(ctx))); // [promise][res][this][count] + duk_call_method(ctx, 1); duk_pop(ctx); // [promise] +#else + void **data = (void**)ILibMemory_Allocate(2 * sizeof(void*), 0, NULL, NULL); + data[0] = ctx; + data[1] = duk_get_heapptr(ctx, -1); + ILibChain_InitDescriptorCount(duk_ctx_chain(ctx)); + ILibChain_RunOnMicrostackThreadEx2(duk_ctx_chain(ctx), ILibDuktape_DescriptorEvents_GetCount_results, data, 1); +#endif + return(1); +} void ILibDuktape_DescriptorEvents_Push(duk_context *ctx, void *chain) { ILibChain_Link *link = (ILibChain_Link*)ILibChain_Link_Allocate(sizeof(ILibChain_Link), 2 * sizeof(void*)); @@ -2534,7 +2579,7 @@ void ILibDuktape_DescriptorEvents_Push(duk_context *ctx, void *chain) ((void**)link->ExtraMemoryPtr)[1] = duk_get_heapptr(ctx, -1); ILibDuktape_CreateInstanceMethod(ctx, "addDescriptor", ILibDuktape_DescriptorEvents_Add, 2); ILibDuktape_CreateInstanceMethod(ctx, "removeDescriptor", ILibDuktape_DescriptorEvents_Remove, 1); - + ILibDuktape_CreateInstanceMethod(ctx, "getDescriptorCount", ILibDuktape_DescriptorEvents_GetCount, 0); ILibAddToChain(chain, link); } diff --git a/microstack/ILibParsers.c b/microstack/ILibParsers.c index ca17d24..b73da0f 100644 --- a/microstack/ILibParsers.c +++ b/microstack/ILibParsers.c @@ -982,6 +982,7 @@ typedef struct ILibBaseChain #endif int selectTimeout; void *node; + int lastDescriptorCount; }ILibBaseChain; @@ -3371,9 +3372,9 @@ ILibExportMethod void ILibStartChain(void *Chain) // chain->node = ILibLinkedList_GetNode_Head(chain->Links); chain->selectTimeout = (int)((tv.tv_sec * 1000) + (tv.tv_usec / 1000)); - while(chain->node!=NULL && (module=(ILibChain_Link*)ILibLinkedList_GetDataFromNode(chain->node))!=NULL) + while (chain->node != NULL && (module = (ILibChain_Link*)ILibLinkedList_GetDataFromNode(chain->node)) != NULL) { - if(module->PreSelectHandler != NULL) + if (module->PreSelectHandler != NULL) { #ifdef MEMORY_CHECK #ifdef WIN32 @@ -3404,7 +3405,7 @@ ILibExportMethod void ILibStartChain(void *Chain) FD_SET(chain->TerminatePipe[0], &readset); #endif sem_wait(&ILibChainLock); - while(ILibLinkedList_GetCount(((ILibBaseChain*)Chain)->LinksPendingDelete) > 0) + while (ILibLinkedList_GetCount(((ILibBaseChain*)Chain)->LinksPendingDelete) > 0) { chain->node = ILibLinkedList_GetNode_Head(((ILibBaseChain*)Chain)->LinksPendingDelete); module = (ILibChain_Link*)ILibLinkedList_GetDataFromNode(chain->node); @@ -3427,8 +3428,18 @@ ILibExportMethod void ILibStartChain(void *Chain) DWORD waitTimeout = 0; ILibChain_SetupWindowsWaitObject(chain->WaitHandles, &x, &tv, &waitTimeout, &readset, &writeset, &errorset, chain->auxSelectHandles, NULL); + chain->lastDescriptorCount = x; slct = ILibChain_WindowsSelect(chain, &readset, &writeset, &errorset, chain->WaitHandles, x, waitTimeout); #else + if (chain->lastDescriptorCount < 0) + { + int z; + chain->lastDescriptorCount = 0; + for (z = 0; z < FD_SETSIZE; ++z) + { + if (FD_ISSET(z, &readset) || FD_ISSET(z, &writeset) || FD_ISSET(z, &errorset)) { chain->lastDescriptorCount += 1; } + } + } slct = select(FD_SETSIZE, &readset, &writeset, &errorset, &tv); #endif chain->PostSelectCount++; @@ -3619,6 +3630,15 @@ ILibExportMethod void ILibStartChain(void *Chain) free(Chain); } +void ILibChain_InitDescriptorCount(void *chain) +{ + ((ILibBaseChain*)chain)->lastDescriptorCount = -1; +} +int ILibChain_GetDescriptorCount(void *chain) +{ + return(((ILibBaseChain*)chain)->lastDescriptorCount); +} + /*! \fn ILibStopChain(void *Chain) \brief Stops a chain \par diff --git a/microstack/ILibParsers.h b/microstack/ILibParsers.h index 21047e1..701a427 100644 --- a/microstack/ILibParsers.h +++ b/microstack/ILibParsers.h @@ -1003,7 +1003,8 @@ int ILibIsRunningOnChainThread(void* chain); #define tv2LTEtv1(ptv1, ptv2) (tv2LTtv1(ptv2,ptv1) || ((ptv2)->tv_sec == (ptv1)->tv_sec && (ptv2)->tv_usec <= (ptv1)->tv_usec)) #define tvnonzero(ptv) ((ptv)->tv_sec != 0 || (ptv)->tv_usec != 0) #endif - + void ILibChain_InitDescriptorCount(void *chain); + int ILibChain_GetDescriptorCount(void *chain); ILibExportMethod void ILibStartChain(void *chain); ILibExportMethod void ILibStopChain(void *chain); #ifdef WIN32