summaryrefslogtreecommitdiff
path: root/cpp/src/Ice/FactoryTable.cpp
diff options
context:
space:
mode:
authorMichi Henning <michi@zeroc.com>2008-07-08 17:15:16 +1000
committerMichi Henning <michi@zeroc.com>2008-07-08 17:15:16 +1000
commitc49d9f97620053b30ecdfa66581484030865d039 (patch)
tree18803c9334660fad1a069fb8d1a01fe58f202512 /cpp/src/Ice/FactoryTable.cpp
parentBug 2038 - Fixed stale comment from previous fix. (diff)
downloadice-c49d9f97620053b30ecdfa66581484030865d039.tar.bz2
ice-c49d9f97620053b30ecdfa66581484030865d039.tar.xz
ice-c49d9f97620053b30ecdfa66581484030865d039.zip
Squashed commit of the following:
commit 3677312fda0e2e230d5572b3e76b3d1758c86919 Author: Michi Henning <michi@zeroc.com> Date: Tue Jul 8 17:08:15 2008 +1000 Bug 2038 - Ctrl-C on Windows without CtrlCHandler Renamed FactoryTableDef -> FactoryTable Renamed FactoryTable -> FactoryTableInit
Diffstat (limited to 'cpp/src/Ice/FactoryTable.cpp')
-rw-r--r--cpp/src/Ice/FactoryTable.cpp149
1 files changed, 123 insertions, 26 deletions
diff --git a/cpp/src/Ice/FactoryTable.cpp b/cpp/src/Ice/FactoryTable.cpp
index 6ac1f72cbe9..8eb491f829e 100644
--- a/cpp/src/Ice/FactoryTable.cpp
+++ b/cpp/src/Ice/FactoryTable.cpp
@@ -10,53 +10,150 @@
#include <Ice/FactoryTable.h>
#include <Ice/UserExceptionFactory.h>
-namespace IceInternal
-{
+#ifdef __APPLE__
+# include <dlfcn.h>
+#endif
//
-// Single global instance of the factory table for non-local
-// exceptions and non-abstract classes.
+// Add a factory to the exception factory table.
+// If the factory is present already, increment its reference count.
//
-ICE_DECLSPEC_EXPORT FactoryTableDef* factoryTable;
-
+void
+IceInternal::FactoryTable::addExceptionFactory(const std::string& t, const IceInternal::UserExceptionFactoryPtr& f)
+{
+ IceUtil::Mutex::Lock lock(_m);
+ EFTable::iterator i = _eft.find(t);
+ if(i == _eft.end())
+ {
+ _eft[t] = EFPair(f, 1);
+ }
+ else
+ {
+ i->second.second++;
+ }
}
-namespace
+//
+// Return the exception factory for a given type ID
+//
+IceInternal::UserExceptionFactoryPtr
+IceInternal::FactoryTable::getExceptionFactory(const std::string& t) const
{
+ IceUtil::Mutex::Lock lock(_m);
+ EFTable::const_iterator i = _eft.find(t);
+#ifdef __APPLE__
+ if(i == _eft.end())
+ {
+ lock.release();
-static int initCount = 0; // Initialization count
-IceUtil::StaticMutex initCountMutex = ICE_STATIC_MUTEX_INITIALIZER;
+ //
+ // Try to find the symbol, if found this should trigger the
+ // object static constructors to be called.
+ //
+ std::string symbol = "__F";
+ for(std::string::const_iterator p = t.begin(); p != t.end(); ++p)
+ {
+ symbol += ((*p) == ':') ? '_' : *p;
+ }
+ symbol += "__initializer";
+ dlsym(RTLD_DEFAULT, symbol.c_str());
+ lock.acquire();
+ i = _eft.find(t);
+ }
+#endif
+ return i != _eft.end() ? i->second.first : IceInternal::UserExceptionFactoryPtr();
}
//
-// This constructor initializes the single global
-// IceInternal::factoryTable instance from the outside (if it hasn't
-// been initialized yet). The constructor here is triggered by a
-// file-static instance of FactoryTable in each slice2cpp-generated
-// header file that uses non-local exceptions or non-abstract classes.
-// This ensures that IceInternal::factoryTable is always initialized
-// before it is used.
+// Remove a factory from the exception factory table. If the factory
+// is not present, do nothing; otherwise, decrement the factory's
+// reference count; if the count drops to zero, remove the factory's
+// entry from the table.
//
-IceInternal::FactoryTable::FactoryTable()
+void
+IceInternal::FactoryTable::removeExceptionFactory(const std::string& t)
{
- IceUtil::StaticMutex::Lock lock(initCountMutex);
- if(0 == initCount++)
+ IceUtil::Mutex::Lock lock(_m);
+ EFTable::iterator i = _eft.find(t);
+ if(i != _eft.end())
{
- factoryTable = new FactoryTableDef;
+ if(--i->second.second == 0)
+ {
+ _eft.erase(i);
+ }
}
}
//
-// The destructor decrements the reference count and, once the
-// count drops to zero, deletes the table.
+// Add a factory to the object factory table.
//
-IceInternal::FactoryTable::~FactoryTable()
+void
+IceInternal::FactoryTable::addObjectFactory(const std::string& t, const Ice::ObjectFactoryPtr& f)
{
- IceUtil::StaticMutex::Lock lock(initCountMutex);
- if(0 == --initCount)
+ IceUtil::Mutex::Lock lock(_m);
+ OFTable::iterator i = _oft.find(t);
+ if(i == _oft.end())
+ {
+ _oft[t] = OFPair(f, 1);
+ }
+ else
{
- delete factoryTable;
+ i->second.second++;
}
}
+
+//
+// Return the object factory for a given type ID
+//
+Ice::ObjectFactoryPtr
+IceInternal::FactoryTable::getObjectFactory(const std::string& t) const
+{
+ IceUtil::Mutex::Lock lock(_m);
+ OFTable::const_iterator i = _oft.find(t);
+#ifdef __APPLE__
+ if(i == _oft.end())
+ {
+ lock.release();
+
+ //
+ // Try to find the symbol, if found this should trigger the
+ // object static constructors to be called.
+ //
+ std::string symbol = "__F";
+ for(std::string::const_iterator p = t.begin(); p != t.end(); ++p)
+ {
+ symbol += ((*p) == ':') ? '_' : *p;
+ }
+ symbol += "__initializer";
+ dlsym(RTLD_DEFAULT, symbol.c_str());
+
+ lock.acquire();
+
+ i = _oft.find(t);
+ }
+#endif
+ return i != _oft.end() ? i->second.first : Ice::ObjectFactoryPtr();
+}
+
+//
+// Remove a factory from the object factory table. If the factory
+// is not present, do nothing; otherwise, decrement the factory's
+// reference count if the count drops to zero, remove the factory's
+// entry from the table.
+//
+void
+IceInternal::FactoryTable::removeObjectFactory(const std::string& t)
+{
+ IceUtil::Mutex::Lock lock(_m);
+ OFTable::iterator i = _oft.find(t);
+ if(i != _oft.end())
+ {
+ if(--i->second.second == 0)
+ {
+ _oft.erase(i);
+ }
+ }
+}
+