Use epicsThreadOnce for safe lazy initialization
Also use epicsAtExit to handle cleanup.
This commit is contained in:
@@ -7,6 +7,8 @@
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <stdexcept>
|
||||
#include <epicsThread.h>
|
||||
#include <epicsExit.h>
|
||||
#include <lock.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
*/
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <epicsThread.h>
|
||||
#include <epicsExit.h>
|
||||
#include <lock.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
+17
-33
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <epicsThread.h>
|
||||
#include <epicsEvent.h>
|
||||
#include <epicsExit.h>
|
||||
#include "lock.h"
|
||||
#include "event.h"
|
||||
#include "thread.h"
|
||||
@@ -47,41 +48,25 @@ class ThreadListElement;
|
||||
typedef LinkedListNode<ThreadListElement> ThreadListNode;
|
||||
typedef LinkedList<ThreadListElement> 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;
|
||||
|
||||
Reference in New Issue
Block a user