From 9b5c5021425eead08aada843dae4ad009fb23967 Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Sat, 3 Jun 2000 01:19:29 +0000 Subject: [PATCH] use thread once during initialization --- src/ca/access.cpp | 90 +++++++++++++++++------------ src/ca/cac.cpp | 31 ++++++---- src/libCom/osi/os/WIN32/osdThread.c | 9 ++- 3 files changed, 82 insertions(+), 48 deletions(-) diff --git a/src/ca/access.cpp b/src/ca/access.cpp index 39eb6d8a6..2a50a8168 100644 --- a/src/ca/access.cpp +++ b/src/ca/access.cpp @@ -34,7 +34,23 @@ threadPrivateId caClientContextId; threadPrivateId cacRecursionLock; -#define TYPENOTINUSE (-2) +static threadOnceId caClientContextIdOnce = OSITHREAD_ONCE_INIT; + +extern "C" void ca_client_exit_handler () +{ + if ( caClientContextId ) { + threadPrivateDelete ( caClientContextId ); + caClientContextId = 0; + } +} + +static void ca_init_client_context ( void * dummy ) +{ + caClientContextId = threadPrivateCreate (); + if ( caClientContextId ) { + atexit ( ca_client_exit_handler ); + } +} /* * fetchClientContext (); @@ -43,17 +59,21 @@ int fetchClientContext (cac **ppcac) { int status; - if ( caClientContextId != NULL ) { - *ppcac = (cac *) threadPrivateGet (caClientContextId); - if (*ppcac) { - return ECA_NORMAL; - } + threadOnce ( &caClientContextIdOnce, ca_init_client_context, 0 ); + + if ( caClientContextId == 0 ) { + return ECA_ALLOCMEM; + } + + *ppcac = (cac *) threadPrivateGet ( caClientContextId ); + if ( *ppcac ) { + return ECA_NORMAL; } status = ca_task_initialize (); - if (status == ECA_NORMAL) { + if ( status == ECA_NORMAL ) { *ppcac = (cac *) threadPrivateGet (caClientContextId); - if (!*ppcac) { + if ( ! *ppcac ) { status = ECA_INTERNAL; } } @@ -87,18 +107,6 @@ extern "C" void ca_default_exception_handler (struct exception_handler_args args } } -extern "C" void caClientExitHandler () -{ - if ( caClientContextId ) { - threadPrivateDelete ( caClientContextId ); - caClientContextId = 0; - } - if ( cacRecursionLock ) { - threadPrivateDelete ( cacRecursionLock ); - cacRecursionLock = 0; - } -} - /* * ca_task_initialize () */ @@ -106,23 +114,24 @@ int epicsShareAPI ca_task_initialize (void) { cac *pcac; - if (caClientContextId==NULL) { - caClientContextId = threadPrivateCreate (); - if (!caClientContextId) { - return ECA_ALLOCMEM; - } - atexit (caClientExitHandler); + threadOnce ( &caClientContextIdOnce, ca_init_client_context, 0); + + if ( caClientContextId == 0 ) { + return ECA_ALLOCMEM; } - pcac = (cac *) threadPrivateGet (caClientContextId); - if (pcac) { + pcac = (cac *) threadPrivateGet ( caClientContextId ); + if ( pcac ) { return ECA_NORMAL; } pcac = new cac; - if (!pcac) { + if ( ! pcac ) { return ECA_ALLOCMEM; } + + threadPrivateSet ( caClientContextId, (void *) pcac ); + return ECA_NORMAL; } @@ -180,9 +189,10 @@ epicsShareFunc int epicsShareAPI ca_task_exit (void) cac *pcac; if ( caClientContextId != NULL ) { - pcac = (cac *) threadPrivateGet (caClientContextId); - if (pcac) { + pcac = (cac *) threadPrivateGet ( caClientContextId ); + if ( pcac ) { delete pcac; + threadPrivateSet ( caClientContextId, 0 ); } } @@ -432,7 +442,7 @@ int epicsShareAPI ca_pend (ca_real timeout, int early) return status; } - return pcac->pend (timeout, early); + return pcac->pend ( timeout, early ); } /* @@ -570,7 +580,7 @@ void epicsShareAPI ca_signal_formated (long ca_status, const char *pfilenm, }; if (caClientContextId) { - pcac = (cac *) threadPrivateGet (caClientContextId); + pcac = (cac *) threadPrivateGet ( caClientContextId ); } else { pcac = NULL; @@ -730,7 +740,7 @@ int ca_vPrintf (const char *pformat, va_list args) caPrintfFunc *ca_printf_func; if ( caClientContextId ) { - cac *pcac = (cac *) threadPrivateGet (caClientContextId); + cac *pcac = (cac *) threadPrivateGet ( caClientContextId ); if (pcac) { ca_printf_func = pcac->ca_printf_func; } @@ -893,8 +903,8 @@ epicsShareFunc int epicsShareAPI ca_channel_status (threadId /* tid */) */ epicsShareFunc int epicsShareAPI ca_current_context (caClientCtx *pCurrentContext) { - if (caClientContextId) { - void *pCtx = threadPrivateGet (caClientContextId); + if ( caClientContextId ) { + void *pCtx = threadPrivateGet ( caClientContextId ); if (pCtx) { *pCurrentContext = pCtx; return ECA_NORMAL; @@ -916,7 +926,13 @@ epicsShareFunc int epicsShareAPI ca_current_context (caClientCtx *pCurrentContex */ epicsShareFunc int epicsShareAPI ca_attach_context (caClientCtx context) { - threadPrivateSet (caClientContextId, context); + cac *pcac; + + pcac = (cac *) threadPrivateGet ( caClientContextId ); + if ( pcac && context != 0 ) { + return ECA_ISATTACHED; + } + threadPrivateSet ( caClientContextId, context ); return ECA_NORMAL; } diff --git a/src/ca/cac.cpp b/src/ca/cac.cpp index d3bbacefa..1b6a8bc31 100644 --- a/src/ca/cac.cpp +++ b/src/ca/cac.cpp @@ -16,6 +16,21 @@ #include "inetAddrID_IL.h" #include "bhe_IL.h" +extern "C" void cacRecursionLockExitHandler () +{ + if ( cacRecursionLock ) { + threadPrivateDelete ( cacRecursionLock ); + cacRecursionLock = 0; + } +} + +static void cacInitRecursionLock ( void * dummy ) +{ + cacRecursionLock = threadPrivateCreate (); + if ( cacRecursionLock ) { + atexit ( cacRecursionLockExitHandler ); + } +} // // cac::cac () @@ -29,15 +44,15 @@ cac::cac () : pndrecvcnt (0) { long status; + static threadOnceId once = OSITHREAD_ONCE_INIT; - if ( cacRecursionLock == NULL ) { - cacRecursionLock = threadPrivateCreate (); - if ( ! cacRecursionLock ) { - throwWithLocation ( caErrorCode (ECA_ALLOCMEM) ); - } + threadOnce ( &once, cacInitRecursionLock, 0); + + if ( cacInitRecursionLock == 0 ) { + throwWithLocation ( caErrorCode (ECA_ALLOCMEM) ); } - if ( ! osiSockAttach() ) { + if ( ! osiSockAttach () ) { throwWithLocation ( caErrorCode (ECA_INTERNAL) ); } @@ -129,8 +144,6 @@ cac::cac () : free (this->ca_pHostName); throwWithLocation ( caErrorCode (ECA_ALLOCMEM) ); } - - threadPrivateSet (caClientContextId, (void *) this); } /* @@ -140,8 +153,6 @@ cac::cac () : */ cac::~cac () { - threadPrivateSet (caClientContextId, NULL); - // // destroy local IO channels // diff --git a/src/libCom/osi/os/WIN32/osdThread.c b/src/libCom/osi/os/WIN32/osdThread.c index 99b1e1198..431aeddbe 100644 --- a/src/libCom/osi/os/WIN32/osdThread.c +++ b/src/libCom/osi/os/WIN32/osdThread.c @@ -557,7 +557,14 @@ epicsShareFunc void epicsShareAPI threadOnceOsd ( BOOL success; DWORD stat; - stat = WaitForSingleObject (win32ThreadGlobalMutex, INFINITE); + if ( ! win32ThreadInitOK ) { + threadInit (); + if ( ! win32ThreadInitOK ) { + return NULL; + } + } + + stat = WaitForSingleObject ( win32ThreadGlobalMutex, INFINITE ); assert ( stat == WAIT_OBJECT_0 ); if (!*id) {