diff --git a/pvDataApp/Makefile b/pvDataApp/Makefile index d79b6f9..50c3f87 100644 --- a/pvDataApp/Makefile +++ b/pvDataApp/Makefile @@ -23,6 +23,7 @@ INC += messageQueue.h INC += destroyable.h INC += status.h INC += sharedPtr.h +INC += localStaticLock.h LIBSRCS += byteBuffer.cpp LIBSRCS += bitSet.cpp @@ -35,6 +36,7 @@ LIBSRCS += timeFunction.cpp LIBSRCS += timer.cpp LIBSRCS += status.cpp LIBSRCS += messageQueue.cpp +LIBSRCS += localStaticLock.cpp SRC_DIRS += $(PVDATA)/pv diff --git a/pvDataApp/factory/FieldCreateFactory.cpp b/pvDataApp/factory/FieldCreateFactory.cpp index 976a091..8840b94 100644 --- a/pvDataApp/factory/FieldCreateFactory.cpp +++ b/pvDataApp/factory/FieldCreateFactory.cpp @@ -528,10 +528,11 @@ FieldConstPtr FieldCreate::deserialize(ByteBuffer* buffer, DeserializableControl FieldCreatePtr FieldCreate::getFieldCreate() { - static FieldCreatePtr fieldCreate; - static Mutex mutex; - Lock xx(mutex); + LOCAL_STATIC_LOCK; + static FieldCreatePtr fieldCreate; + static Mutex mutex; + Lock xx(mutex); if(fieldCreate.get()==0) fieldCreate = FieldCreatePtr(new FieldCreate()); return fieldCreate; } diff --git a/pvDataApp/misc/localStaticLock.cpp b/pvDataApp/misc/localStaticLock.cpp new file mode 100644 index 0000000..8f0360b --- /dev/null +++ b/pvDataApp/misc/localStaticLock.cpp @@ -0,0 +1,39 @@ +/* localStaticLock.cpp */ +/** + * Copyright - See the COPYRIGHT that is included with this distribution. + * EPICS pvData is distributed subject to a Software License Agreement found + * in file LICENSE that is included with this distribution. + */ +/** + * @author mse + */ + +#include + +static int nifty_counter; +static epics::pvData::Mutex* g_localStaticInitMutex; + +epics::pvData::Mutex& getLocalStaticInitMutex() +{ + return *g_localStaticInitMutex; +} + + +// The counter is initialized at load-time, i.e., before any of the static objects are initialized. +MutexInitializer::MutexInitializer () +{ + if (0 == nifty_counter++) + { + // Initialize static members. + g_localStaticInitMutex = new epics::pvData::Mutex(); + } +} + +MutexInitializer::~MutexInitializer () +{ + if (0 == --nifty_counter) + { + // Clean-up. + delete g_localStaticInitMutex; + } +} diff --git a/pvDataApp/misc/localStaticLock.h b/pvDataApp/misc/localStaticLock.h new file mode 100644 index 0000000..db2b365 --- /dev/null +++ b/pvDataApp/misc/localStaticLock.h @@ -0,0 +1,31 @@ +/* localStaticLock.h */ +/** + * Copyright - See the COPYRIGHT that is included with this distribution. + * EPICS pvData is distributed subject to a Software License Agreement found + * in file LICENSE that is included with this distribution. + */ +/** + * @author mse + */ +#ifndef LOCALSTATICLOCK_H +#define LOCALSTATICLOCK_H + +#include + +extern epics::pvData::Mutex& getLocalStaticInitMutex(); + +#if defined(__GNUC__) && __GNUC__ >= 4 +// noop +#define LOCAL_STATIC_LOCK +#else +#define LOCAL_STATIC_LOCK epics::pvData::Lock localStaticInitMutexLock(getLocalStaticInitMutex()); +#endif + +static class MutexInitializer { + public: + MutexInitializer (); + ~MutexInitializer (); +} localStaticMutexInitializer; // Note object here in the header. + + +#endif /* LOCALSTATICLOCK_H */ diff --git a/pvDataApp/pv/pvType.h b/pvDataApp/pv/pvType.h index 821e66c..93eb1f2 100644 --- a/pvDataApp/pv/pvType.h +++ b/pvDataApp/pv/pvType.h @@ -27,6 +27,7 @@ typedef unsigned int uintptr_t; #endif #include +#include namespace epics { namespace pvData {