summaryrefslogtreecommitdiff
path: root/cpp/include/IceUtil/ObjectBase.h
diff options
context:
space:
mode:
authorMichi Henning <michi@zeroc.com>2003-10-20 23:18:23 +0000
committerMichi Henning <michi@zeroc.com>2003-10-20 23:18:23 +0000
commit8941640745d51e543fadc0524368d5f861691152 (patch)
tree384020f2b665d7f1a1c20b5ea435e0bf74faf476 /cpp/include/IceUtil/ObjectBase.h
parentmerging changes from garbage collector (diff)
downloadice-8941640745d51e543fadc0524368d5f861691152.tar.bz2
ice-8941640745d51e543fadc0524368d5f861691152.tar.xz
ice-8941640745d51e543fadc0524368d5f861691152.zip
merging changes for garbage collector
Diffstat (limited to 'cpp/include/IceUtil/ObjectBase.h')
-rw-r--r--cpp/include/IceUtil/ObjectBase.h149
1 files changed, 149 insertions, 0 deletions
diff --git a/cpp/include/IceUtil/ObjectBase.h b/cpp/include/IceUtil/ObjectBase.h
new file mode 100644
index 00000000000..52467486793
--- /dev/null
+++ b/cpp/include/IceUtil/ObjectBase.h
@@ -0,0 +1,149 @@
+// **********************************************************************
+//
+// Copyright (c) 2003
+// ZeroC, Inc.
+// Billerica, MA, USA
+//
+// All Rights Reserved.
+//
+// Ice is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License version 2 as published by
+// the Free Software Foundation.
+//
+// **********************************************************************
+
+#ifndef ICE_UTIL_OBJECTBASE_H
+#define ICE_UTIL_OBJECTBASE_H
+
+#include <IceUtil/StaticRecMutex.h>
+#include <set>
+
+namespace IceUtil
+{
+
+extern ICE_UTIL_API StaticRecMutex gcMutex;
+
+class GC;
+class ObjectBase;
+
+typedef std::set<ObjectBase*> ObjectSet;
+extern ICE_UTIL_API ObjectSet objects; // Set of pointers to all existing classes.
+
+typedef std::multiset<ObjectBase*> ObjectMultiSet;
+
+class ICE_UTIL_API ObjectBase : public noncopyable
+{
+public:
+
+ ObjectBase();
+ virtual ~ObjectBase();
+ void __incRef();
+ void __decRef();
+ int __getRef() const;
+ void __setNoDelete(bool);
+ void __decRefUnsafe();
+
+protected:
+
+ static void __addObject(ObjectMultiSet&, ObjectBase*);
+ virtual void __gcReachable(ObjectMultiSet&) const = 0;
+ virtual void __gcClear() = 0;
+
+private:
+
+ int _ref;
+ bool _noDelete;
+ bool _adopted;
+
+ friend class IceUtil::GC;
+};
+
+inline
+ObjectBase::ObjectBase()
+{
+ gcMutex.lock();
+ _ref = 0;
+ _noDelete = false;
+ _adopted = false;
+ gcMutex.unlock();
+}
+
+inline
+ObjectBase::~ObjectBase()
+{
+ gcMutex.lock();
+ ObjectSet::size_type num = objects.erase(this);
+ assert(num == 1);
+ gcMutex.unlock();
+}
+
+inline void
+ObjectBase::__incRef()
+{
+ gcMutex.lock();
+ assert(_ref >= 0);
+ if(!_adopted && _ref == 0)
+ {
+ _adopted = true;
+ std::pair<ObjectSet::iterator, bool> rc = objects.insert(this);
+ assert(rc.second);
+ }
+ ++_ref;
+ gcMutex.unlock();
+}
+
+inline void
+ObjectBase::__decRef()
+{
+ gcMutex.lock();
+ bool doDelete = false;
+ assert(_ref > 0);
+ if(--_ref == 0)
+ {
+ doDelete = !_noDelete;
+ _noDelete = true;
+ }
+ if(doDelete)
+ {
+ delete this;
+ }
+ gcMutex.unlock();
+}
+
+inline int
+ObjectBase::__getRef() const
+{
+ gcMutex.lock();
+ int ref = _ref;
+ gcMutex.unlock();
+ return ref;
+}
+
+inline void
+ObjectBase::__setNoDelete(bool b)
+{
+ gcMutex.lock();
+ _noDelete = b;
+ gcMutex.unlock();
+}
+
+inline void
+ObjectBase::__decRefUnsafe()
+{
+ --_ref;
+}
+
+inline void
+ObjectBase::__addObject(ObjectMultiSet& c, ObjectBase* p)
+{
+ gcMutex.lock();
+ if(p)
+ {
+ c.insert(p);
+ }
+ gcMutex.unlock();
+}
+
+}
+
+#endif