diff options
Diffstat (limited to 'ACE/ace/Cleanup.cpp')
-rw-r--r-- | ACE/ace/Cleanup.cpp | 192 |
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 |