libCom "join" win32 threads

Wait for completion
This commit is contained in:
Michael Davidsaver
2018-04-05 09:04:46 -07:00
parent c9dcab95a6
commit 460e58e3e5
2 changed files with 38 additions and 3 deletions
+36 -1
View File
@@ -32,6 +32,7 @@
#include "epicsAssert.h"
#include "ellLib.h"
#include "epicsExit.h"
#include "epicsAtomic.h"
epicsShareFunc void osdThreadHooksRun(epicsThreadId id);
@@ -46,6 +47,7 @@ typedef struct win32ThreadGlobal {
typedef struct epicsThreadOSD {
ELLNODE node;
int refcnt;
HANDLE handle;
EPICSTHREADFUNC funptr;
void * parm;
@@ -53,6 +55,7 @@ typedef struct epicsThreadOSD {
DWORD id;
unsigned epicsPriority;
char isSuspended;
char joinable;
} win32ThreadParam;
typedef struct epicsThreadPrivateOSD {
@@ -238,6 +241,8 @@ static void epicsParmCleanupWIN32 ( win32ThreadParam * pParm )
}
if ( pParm ) {
if(epicsAtomicDecrIntT(&pParm->refcnt) > 0) return;
/* fprintf ( stderr, "thread %s is exiting\n", pParm->pName ); */
EnterCriticalSection ( & pGbl->mutex );
ellDelete ( & pGbl->threadList, & pParm->node );
@@ -533,6 +538,7 @@ static win32ThreadParam * epicsThreadParmCreate ( const char *pName )
pParmWIN32->pName = (char *) ( pParmWIN32 + 1 );
strcpy ( pParmWIN32->pName, pName );
pParmWIN32->isSuspended = 0;
epicsAtomicIncrIntT(&pParmWIN32->refcnt);
}
return pParmWIN32;
}
@@ -648,10 +654,39 @@ epicsThreadId epicsThreadCreateOpt (
return NULL;
}
if(opts->joinable) {
pParmWIN32->joinable = 1;
epicsAtomicIncrIntT(&pParmWIN32->refcnt);
}
return ( epicsThreadId ) pParmWIN32;
}
void epicsThreadJoin(epicsThreadId id) {}
void epicsThreadJoin(epicsThreadId id)
{
win32ThreadParam * pParmWIN32 = id;
if(!id) {
/* no-op */
} else if(!pParmWIN32->joinable) {
/* try to error nicely, however in all likelyhood de-ref of
* 'pParmWIN32' has already crashed us as we are racing thread exit,
* which free's 'pParmWIN32'.
*/
cantProceed("%s join not enabled for thread.\n", pParmWIN32->pName);
} else if(epicsThreadGetIdSelf() != id) {
DWORD status = WaitForSingleObject(pParmWIN32->handle, INFINITE);
if(status != WAIT_OBJECT_0) {
/* TODO: signal error? */
}
epicsParmCleanupWIN32(pParmWIN32);
} else {
/* join self silently does nothing */
epicsParmCleanupWIN32(pParmWIN32);
}
}
/*
* epicsThreadSuspendSelf ()
+2 -2
View File
@@ -11,7 +11,7 @@
#ifndef osdThreadh
#define osdThreadh
/* This target does not support joining threads */
#define EPICS_THREAD_CAN_JOIN (0)
/* This target supports joining threads */
#define EPICS_THREAD_CAN_JOIN (1)
#endif /* osdThreadh */