summaryrefslogtreecommitdiff
path: root/ACE/ace/Cleanup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/ace/Cleanup.cpp')
-rw-r--r--ACE/ace/Cleanup.cpp192
1 files changed, 192 insertions, 0 deletions
diff --git a/ACE/ace/Cleanup.cpp b/ACE/ace/Cleanup.cpp
new file mode 100644
index 00000000000..a6fc5de6a78
--- /dev/null
+++ b/ACE/ace/Cleanup.cpp
@@ -0,0 +1,192 @@
+// $Id$
+
+#include "ace/Cleanup.h"
+
+ACE_RCSID (ace,
+ Cleanup,
+ "$Id$")
+
+#if !defined (ACE_HAS_INLINED_OSCALLS)
+# include "ace/Cleanup.inl"
+#endif /* ACE_HAS_INLINED_OSCALLS */
+
+#include "ace/OS_Memory.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+void
+ACE_Cleanup::cleanup (void *)
+{
+ delete this;
+}
+
+
+ACE_Cleanup::~ACE_Cleanup (void)
+{
+}
+
+/*****************************************************************************/
+
+extern "C" void
+ACE_CLEANUP_DESTROYER_NAME (ACE_Cleanup *object, void *param)
+{
+ object->cleanup (param);
+}
+
+/*****************************************************************************/
+
+ACE_Cleanup_Info::ACE_Cleanup_Info (void)
+ : object_ (0),
+ cleanup_hook_ (0),
+ param_ (0)
+{
+}
+
+bool
+ACE_Cleanup_Info::operator== (const ACE_Cleanup_Info &o) const
+{
+ return o.object_ == this->object_
+ && o.cleanup_hook_ == this->cleanup_hook_
+ && o.param_ == this->param_;
+}
+
+bool
+ACE_Cleanup_Info::operator!= (const ACE_Cleanup_Info &o) const
+{
+ return !(*this == o);
+}
+
+/*****************************************************************************/
+
+/**
+ * @class ACE_Cleanup_Info_Node
+ *
+ * @brief For maintaining a list of ACE_Cleanup_Info items.
+ *
+ * For internal use by ACE_Object_Manager.
+ */
+class ACE_Cleanup_Info_Node
+{
+public:
+ ACE_Cleanup_Info_Node (void);
+ ACE_Cleanup_Info_Node (const ACE_Cleanup_Info &new_info,
+ ACE_Cleanup_Info_Node *next);
+ ~ACE_Cleanup_Info_Node (void);
+ ACE_Cleanup_Info_Node *insert (const ACE_Cleanup_Info &);
+private:
+ ACE_Cleanup_Info cleanup_info_;
+ ACE_Cleanup_Info_Node *next_;
+
+ friend class ACE_OS_Exit_Info;
+};
+
+ACE_Cleanup_Info_Node::ACE_Cleanup_Info_Node (void)
+ : cleanup_info_ (),
+ next_ (0)
+{
+}
+
+ACE_Cleanup_Info_Node::ACE_Cleanup_Info_Node (const ACE_Cleanup_Info &new_info,
+ ACE_Cleanup_Info_Node *next)
+ : cleanup_info_ (new_info),
+ next_ (next)
+{
+}
+
+ACE_Cleanup_Info_Node::~ACE_Cleanup_Info_Node (void)
+{
+ delete next_;
+}
+
+ACE_Cleanup_Info_Node *
+ACE_Cleanup_Info_Node::insert (const ACE_Cleanup_Info &new_info)
+{
+ ACE_Cleanup_Info_Node *new_node = 0;
+
+ ACE_NEW_RETURN (new_node,
+ ACE_Cleanup_Info_Node (new_info, this),
+ 0);
+
+ return new_node;
+}
+
+/*****************************************************************************/
+
+ACE_OS_Exit_Info::ACE_OS_Exit_Info (void)
+{
+ ACE_NEW (registered_objects_, ACE_Cleanup_Info_Node);
+}
+
+ACE_OS_Exit_Info::~ACE_OS_Exit_Info (void)
+{
+ delete registered_objects_;
+ registered_objects_ = 0;
+}
+
+int
+ACE_OS_Exit_Info::at_exit_i (void *object,
+ ACE_CLEANUP_FUNC cleanup_hook,
+ void *param)
+{
+ ACE_Cleanup_Info new_info;
+ new_info.object_ = object;
+ new_info.cleanup_hook_ = cleanup_hook;
+ new_info.param_ = param;
+
+ // Return -1 and sets errno if unable to allocate storage. Enqueue
+ // at the head and dequeue from the head to get LIFO ordering.
+
+ ACE_Cleanup_Info_Node *new_node = 0;
+
+ if ((new_node = registered_objects_->insert (new_info)) == 0)
+ return -1;
+ else
+ {
+ registered_objects_ = new_node;
+ return 0;
+ }
+}
+
+int
+ACE_OS_Exit_Info::find (void *object)
+{
+ // Check for already in queue, and return 1 if so.
+ for (ACE_Cleanup_Info_Node *iter = registered_objects_;
+ iter && iter->next_ != 0;
+ iter = iter->next_)
+ {
+ if (iter->cleanup_info_.object_ == object)
+ {
+ // The object has already been registered.
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+void
+ACE_OS_Exit_Info::call_hooks (void)
+{
+ // Call all registered cleanup hooks, in reverse order of
+ // registration.
+ for (ACE_Cleanup_Info_Node *iter = registered_objects_;
+ iter && iter->next_ != 0;
+ iter = iter->next_)
+ {
+ ACE_Cleanup_Info &info = iter->cleanup_info_;
+ if (info.cleanup_hook_ == reinterpret_cast<ACE_CLEANUP_FUNC> (
+ ACE_CLEANUP_DESTROYER_NAME))
+ // The object is an ACE_Cleanup.
+ ACE_CLEANUP_DESTROYER_NAME (
+ reinterpret_cast<ACE_Cleanup *> (info.object_),
+ info.param_);
+ else if (info.object_ == &ace_exit_hook_marker)
+ // The hook is an ACE_EXIT_HOOK.
+ (* reinterpret_cast<ACE_EXIT_HOOK> (info.cleanup_hook_)) ();
+ else
+ (*info.cleanup_hook_) (info.object_, info.param_);
+ }
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL