libCom/osi: Fix nesting for epicsThreadHooks, add WIN32 implementation, lock traversal
- call (generic) exit hook after calling the (specific) epicsExitCallAtThreadExits() - for start hooks added as 1-2-3, run exit hooks in opposite order: 3-2-1 - add calls to hooks module to WIN32 osdThread.c - add lock/unlock to hook list traversal
This commit is contained in:
@@ -166,8 +166,8 @@ threadWrapper (rtems_task_argument arg)
|
||||
|
||||
epicsThreadRunStartHooks(pthreadInfo);
|
||||
(*v->funptr)(v->parm);
|
||||
epicsThreadRunExitHooks(pthreadInfo);
|
||||
epicsExitCallAtThreadExits ();
|
||||
epicsThreadRunExitHooks(pthreadInfo);
|
||||
taskVarLock ();
|
||||
if (v->back)
|
||||
v->back->forw = v->forw;
|
||||
|
||||
@@ -16,13 +16,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* FIXME:
|
||||
* The Windows implementation for thread hooks is still missing.
|
||||
* epicsThreadHooksInit(); as part of the initialization
|
||||
* epicsThreadRunStartHooks(pthreadInfo); from thread context before the user func runs
|
||||
* epicsThreadRunExitHooks(pthreadInfo); from thread context after the user func exits
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
@@ -233,6 +226,7 @@ static win32ThreadGlobal * fetchWin32ThreadGlobal ( void )
|
||||
pWin32ThreadGlobal = 0;
|
||||
return 0;
|
||||
}
|
||||
epicsThreadHooksInit();
|
||||
|
||||
InterlockedExchange ( & initCompleted, 1 );
|
||||
|
||||
@@ -503,6 +497,7 @@ static unsigned WINAPI epicsWin32ThreadEntry ( LPVOID lpParameter )
|
||||
|
||||
success = TlsSetValue ( pGbl->tlsIndexThreadLibraryEPICS, pParm );
|
||||
if ( success ) {
|
||||
epicsThreadRunStartHooks(pParm);
|
||||
/* printf ( "starting thread %d\n", pParm->id ); */
|
||||
( *pParm->funptr ) ( pParm->parm );
|
||||
/* printf ( "terminating thread %d\n", pParm->id ); */
|
||||
@@ -518,6 +513,8 @@ static unsigned WINAPI epicsWin32ThreadEntry ( LPVOID lpParameter )
|
||||
|
||||
epicsExitCallAtThreadExits ();
|
||||
|
||||
epicsThreadRunExitHooks(pParm);
|
||||
|
||||
/*
|
||||
* CAUTION: !!!! the thread id might continue to be used after this thread exits !!!!
|
||||
*/
|
||||
|
||||
@@ -32,9 +32,11 @@ typedef struct epicsThreadHook {
|
||||
|
||||
static ELLLIST startHooks = ELLLIST_INIT;
|
||||
static ELLLIST exitHooks = ELLLIST_INIT;
|
||||
|
||||
/* Locking could probably be avoided, if elllist implementation was using atomic ops */
|
||||
static epicsMutexId hookLock;
|
||||
|
||||
static void addHook (ELLLIST *list, EPICS_THREAD_HOOK_ROUTINE func)
|
||||
static void addHook (ELLLIST *list, EPICS_THREAD_HOOK_ROUTINE func, int atHead)
|
||||
{
|
||||
epicsThreadHook *pHook;
|
||||
|
||||
@@ -42,29 +44,33 @@ static void addHook (ELLLIST *list, EPICS_THREAD_HOOK_ROUTINE func)
|
||||
if (!pHook) checkStatusOnceReturn(errno,"calloc","epicsThreadAddStartHook");
|
||||
pHook->func = func;
|
||||
epicsMutexLock(hookLock);
|
||||
ellInsert(list, NULL, &pHook->node);
|
||||
if (atHead)
|
||||
ellInsert(list, NULL, &pHook->node);
|
||||
else
|
||||
ellAdd(list, &pHook->node);
|
||||
epicsMutexUnlock(hookLock);
|
||||
}
|
||||
|
||||
static void runHooks (ELLLIST *list, epicsThreadId id) {
|
||||
epicsThreadHook *pHook;
|
||||
|
||||
/* As we're only ever inserting hooks at the head of the list, forward traversing is safe */
|
||||
epicsMutexLock(hookLock);
|
||||
pHook = (epicsThreadHook *) ellFirst(list);
|
||||
while (pHook) {
|
||||
pHook->func(id);
|
||||
pHook = (epicsThreadHook *) ellNext(&pHook->node);
|
||||
}
|
||||
epicsMutexUnlock(hookLock);
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI epicsThreadAddStartHook(EPICS_THREAD_HOOK_ROUTINE hook)
|
||||
{
|
||||
addHook(&startHooks, hook);
|
||||
addHook(&startHooks, hook, 0);
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI epicsThreadAddExitHook(EPICS_THREAD_HOOK_ROUTINE hook)
|
||||
{
|
||||
addHook(&exitHooks, hook);
|
||||
addHook(&exitHooks, hook, 1);
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI epicsThreadHooksInit(void)
|
||||
|
||||
@@ -378,8 +378,8 @@ static void * start_routine(void *arg)
|
||||
|
||||
(*pthreadInfo->createFunc)(pthreadInfo->createArg);
|
||||
|
||||
epicsThreadRunExitHooks(pthreadInfo);
|
||||
epicsExitCallAtThreadExits ();
|
||||
epicsThreadRunExitHooks(pthreadInfo);
|
||||
|
||||
free_threadInfo(pthreadInfo);
|
||||
return(0);
|
||||
|
||||
@@ -165,8 +165,8 @@ static void createFunction(EPICSTHREADFUNC func, void *parm)
|
||||
papTSD = 0;
|
||||
epicsThreadRunStartHooks(pthreadInfo);
|
||||
(*func)(parm);
|
||||
epicsThreadRunExitHooks(pthreadInfo);
|
||||
epicsExitCallAtThreadExits ();
|
||||
epicsThreadRunExitHooks(pthreadInfo);
|
||||
free(papTSD);
|
||||
taskVarDelete(tid,(int *)(char *)&papTSD);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user