diff --git a/microscript/ILibDuktape_GenericMarshal.c b/microscript/ILibDuktape_GenericMarshal.c index c824516..355e34d 100644 --- a/microscript/ILibDuktape_GenericMarshal.c +++ b/microscript/ILibDuktape_GenericMarshal.c @@ -1164,7 +1164,7 @@ duk_ret_t ILibDuktape_GenericMarshal_MethodInvokeAsync(duk_context *ctx) sem_init(&(data->workAvailable), 0, 0); sem_init(&(data->workStarted), 0, 0); sem_init(&(data->workFinished), 0, 0); - data->workerThread = ILibSpawnNormalThread(ILibDuktape_GenericMarshal_MethodInvokeAsync_WorkerRunLoop, data); + data->workerThread = ILibSpawnNormalThreadEx(ILibDuktape_GenericMarshal_MethodInvokeAsync_WorkerRunLoop, data, 0); } } else @@ -1268,7 +1268,7 @@ duk_ret_t ILibDuktape_GenericMarshal_MethodInvokeAsync_wait(duk_context *ctx) sem_init(&(data->workAvailable), 0, 0); sem_init(&(data->workStarted), 0, 0); sem_init(&(data->workFinished), 0, 0); - data->workerThread = ILibSpawnNormalThread(ILibDuktape_GenericMarshal_MethodInvokeAsync_WorkerRunLoop, data); + data->workerThread = ILibSpawnNormalThreadEx(ILibDuktape_GenericMarshal_MethodInvokeAsync_WorkerRunLoop, data, 0); } if (data->waitingForResult == WAITING_FOR_RESULT__DISPATCHER) { return(ILibDuktape_Error(ctx, "This method call is not waitable")); } diff --git a/microscript/ILibDuktape_Helpers.c b/microscript/ILibDuktape_Helpers.c index 1511ce5..a77532c 100644 --- a/microscript/ILibDuktape_Helpers.c +++ b/microscript/ILibDuktape_Helpers.c @@ -669,21 +669,15 @@ void Duktape_SafeDestroyHeap(duk_context *ctx) ILibMemory_Free(threadList); #else int rv; - void *status; - long ts = ILibGetTimeStamp(), ts2; - struct timespec t; - t.tv_sec = 5; - t.tv_nsec = 0; - + struct timespec ts; void *node; + void *thr; + + ILibThread_ms2ts(5000, &ts); while ((node = ILibLinkedList_GetNode_Head(ctxd->threads)) != NULL) { - if ((rv = pthread_timedjoin_np((pthread_t)ILibLinkedList_GetDataFromNode(node), &status, &t)) == 0) - { - t.tv_sec -= (((ts2 = ILibGetTimeStamp()) - ts) / 1000); ts = ts2; - if (t.tv_sec == 0) { break; } - } - else if (rv == ETIMEDOUT) + thr = ILibLinkedList_GetDataFromNode(node); + if ((rv = ILibThread_TimedJoinEx(thr, &ts)) != 0) { break; } diff --git a/microstack/ILibParsers.c b/microstack/ILibParsers.c index 5521e20..d839a32 100644 --- a/microstack/ILibParsers.c +++ b/microstack/ILibParsers.c @@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ +#define _GNU_SOURCE #if defined (__APPLE__) #include @@ -9417,7 +9418,7 @@ void ILIBLOGMESSAGEX(char *format, ...) \param arg Optional Parameter to dispatch [Can be NULL] \return Thread Handle */ -void* ILibSpawnNormalThread(voidfp1 method, void* arg) +void* ILibSpawnNormalThreadEx(voidfp1 method, void* arg, int detached) { #if defined (_POSIX) || defined (__APPLE__) intptr_t result; @@ -9425,8 +9426,8 @@ void* ILibSpawnNormalThread(voidfp1 method, void* arg) pthread_t newThread; fptr = (void*(*)(void*))method; result = (intptr_t)pthread_create(&newThread, NULL, fptr, arg); - pthread_detach(newThread); - return (void*)result; + if (detached != 0) { pthread_detach(newThread); } + return(result == 0 ? (void*)newThread : NULL); #endif #ifdef WIN32 @@ -9438,12 +9439,49 @@ void* ILibSpawnNormalThread(voidfp1 method, void* arg) #endif } +#ifndef WIN32 +int ILibThread_TimedJoinEx(void *thr, struct timespec* timeout) +{ + return(pthread_timedjoin_np((pthread_t)thr, NULL, timeout)); +} +struct timespec *ILibThread_ms2ts(uint32_t ms, struct timespec *ts) +{ + struct timeval tv; + long lv; + + gettimeofday(&tv, NULL); + ts->tv_sec = tv.tv_sec + (ms / 1000); + ts->tv_nsec = tv.tv_usec * 1000; + + ts->tv_sec += (ms / 1000); + ts->tv_nsec += ((ms % 1000) * 1000000); + + if ((lv = ts->tv_nsec % 1000000000) > 0) + { + ts->tv_sec += 1; + ts->tv_nsec = lv; + } + + return(ts); +} +#endif +int ILibThread_TimedJoin(void *thr, uint32_t timeout) +{ +#ifdef WIN32 + return(WaitForSingleObject((HANDLE)thr, timeout) == WAIT_TIMEOUT ? 1 : 0); +#else + struct timespec ts; + return(ILibThread_TimedJoinEx(thr, ILibThread_ms2ts(timeout, &ts))); +#endif +} + void ILibThread_Join(void *thr) { #ifdef WIN32 WaitForSingleObject((HANDLE)thr, INFINITE); #else - pthread_join((pthread_t)thr, NULL); + void *r; + pthread_join((pthread_t)thr, &r); #endif } diff --git a/microstack/ILibParsers.h b/microstack/ILibParsers.h index 3706f02..d3f8cb0 100644 --- a/microstack/ILibParsers.h +++ b/microstack/ILibParsers.h @@ -1432,8 +1432,14 @@ extern void ILib_POSIX_CrashHandler(int code); \ingroup ILibParsers *@{ */ - void* ILibSpawnNormalThread(voidfp1 method, void* arg); + void* ILibSpawnNormalThreadEx(voidfp1 method, void* arg, int detached); + #define ILibSpawnNormalThread(method, arg) ILibSpawnNormalThreadEx(method, arg, 1) void ILibThread_Join(void *thr); + int ILibThread_TimedJoin(void *thr, uint32_t timeout); +#ifndef WIN32 + int ILibThread_TimedJoinEx(void *thr, struct timespec* timeout); + struct timespec *ILibThread_ms2ts(uint32_t ms, struct timespec *ts); +#endif void ILibEndThisThread(); #ifdef WIN32 void ILibHandle_DisableInherit(HANDLE *h);