use thread once during initialization

This commit is contained in:
Jeff Hill
2000-06-03 01:19:29 +00:00
parent a2fd2a5463
commit 9b5c502142
3 changed files with 82 additions and 48 deletions
+53 -37
View File
@@ -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
View File
@@ -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
//
+8 -1
View File
@@ -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) {