diff --git a/pvDataApp/factory/StandardField.cpp b/pvDataApp/factory/StandardField.cpp index 0289efb..6163149 100644 --- a/pvDataApp/factory/StandardField.cpp +++ b/pvDataApp/factory/StandardField.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include #include "pvIntrospect.h" #include "standardField.h" @@ -14,8 +16,6 @@ namespace epics { namespace pvData { -static Mutex globalMutex; -static bool notInited = true; static StandardField* standardField = 0; static String notImplemented("not implemented"); @@ -462,7 +462,7 @@ StandardField::StandardField(){init();} StandardField::~StandardField(){ } -static void myDeleteStatic() +static void myDeleteStatic(void*) { int count = alarmField->getReferenceCount(); if(count!=1) printf("~StandardField() alarmField reference count %d\n",count); @@ -502,16 +502,18 @@ static void myDeleteStatic() enumeratedAlarmField->decReferenceCount(); } +static void myInitStatic(void*) +{ + standardField = new StandardField(); + fieldCreate = getFieldCreate(); + epicsAtExit(&myDeleteStatic,0); +} + +static +epicsThreadOnceId myInitOnce = EPICS_THREAD_ONCE_INIT; + StandardField * getStandardField() { - Lock xx(&globalMutex); - if(notInited) { - notInited = false; - standardField = new StandardField(); - fieldCreate = getFieldCreate(); - ShowConstructDestruct::registerCallback( - "standardField", - 0,0,0,myDeleteStatic); - } + epicsThreadOnce(&myInitOnce,&myInitStatic,0); return standardField; } diff --git a/pvDataApp/factory/StandardPVField.cpp b/pvDataApp/factory/StandardPVField.cpp index a24cb20..2f295cd 100644 --- a/pvDataApp/factory/StandardPVField.cpp +++ b/pvDataApp/factory/StandardPVField.cpp @@ -6,6 +6,8 @@ */ #include #include +#include +#include #include #include "pvIntrospect.h" #include "pvData.h" @@ -16,8 +18,6 @@ namespace epics { namespace pvData { -static Mutex globalMutex; -static bool notInited = true; static StandardField *standardField = 0; static String notImplemented("not implemented"); @@ -329,23 +329,25 @@ public: StandardPVFieldExt(): StandardPVField(){}; }; -static void myDeleteStatic() +static void myDeleteStatic(void*) { delete standardPVField; } +static void myInitStatic(void*) +{ + fieldCreate = getFieldCreate(); + pvDataCreate = getPVDataCreate(); + standardField = getStandardField(); + standardPVField = new StandardPVFieldExt(); + epicsAtExit(&myDeleteStatic, 0); +} + +static +epicsThreadOnceId myInitOnce = EPICS_THREAD_ONCE_INIT; + StandardPVField * getStandardPVField() { - Lock xx(&globalMutex); - if(notInited) { - notInited = false; - fieldCreate = getFieldCreate(); - pvDataCreate = getPVDataCreate(); - standardField = getStandardField(); - standardPVField = new StandardPVFieldExt(); - ShowConstructDestruct::registerCallback( - "standardPVField", - 0,0,0,myDeleteStatic); - } + epicsThreadOnce(&myInitOnce, &myInitStatic, 0); return standardPVField; } diff --git a/pvDataApp/misc/thread.cpp b/pvDataApp/misc/thread.cpp index feb10b8..4e97430 100644 --- a/pvDataApp/misc/thread.cpp +++ b/pvDataApp/misc/thread.cpp @@ -13,6 +13,7 @@ #include #include +#include #include "lock.h" #include "event.h" #include "thread.h" @@ -47,41 +48,25 @@ class ThreadListElement; typedef LinkedListNode ThreadListNode; typedef LinkedList ThreadList; -static volatile int64 totalConstruct = 0; -static volatile int64 totalDestruct = 0; -static Mutex globalMutex; -static bool notInited = true; +PVDATA_REFCOUNT_MONITOR_DEFINE(thread); + +static Mutex listGuard; static ThreadList *threadList; -static int64 getTotalConstruct() -{ - Lock xx(&globalMutex); - return totalConstruct; -} - -static int64 getTotalDestruct() -{ - Lock xx(&globalMutex); - return totalDestruct; -} - -static void deleteStatic() +static void deleteStatic(void*) { delete threadList; } -static void init() +static void init(void*) { - Lock xx(&globalMutex); - if(notInited) { - notInited = false; - threadList = new ThreadList(); - ShowConstructDestruct::registerCallback( - String("thread"), - getTotalConstruct,getTotalDestruct,0,deleteStatic); - } + threadList = new ThreadList(); + epicsAtExit(&deleteStatic,0); } +static +epicsThreadOnceId initOnce = EPICS_THREAD_ONCE_INIT; + class ThreadListElement { public: @@ -136,10 +121,10 @@ ThreadPvt::ThreadPvt(Thread *thread,String name, epicsThreadGetStackSize(epicsThreadStackSmall), myFunc,this)) { - init(); - Lock xx(&globalMutex); + epicsThreadOnce(&initOnce, &init, 0); + PVDATA_REFCOUNT_MONITOR_CONSTRUCT(thread); + Lock x(&listGuard); threadList->addTail(threadListElement->node); - totalConstruct++; } ThreadPvt::~ThreadPvt() @@ -158,11 +143,11 @@ ThreadPvt::~ThreadPvt() message += " is not on threadlist"; throw std::logic_error(message); } + Lock x(&listGuard); threadList->remove(threadListElement->node); delete waitDone; delete threadListElement; - Lock xx(&globalMutex); - totalDestruct++; + PVDATA_REFCOUNT_MONITOR_DESTRUCT(thread); } Thread::Thread(String name,ThreadPriority priority,Runnable *runnable) @@ -192,8 +177,7 @@ ThreadPriority Thread::getPriority() void Thread::showThreads(StringBuilder buf) { - init(); - Lock xx(&globalMutex); + Lock x(&listGuard); ThreadListNode *node = threadList->getHead(); while(node!=0) { Thread *thread = node->getObject()->thread;