use thread once during initialization
This commit is contained in:
+53
-37
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+21
-10
@@ -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
|
||||
//
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user