ACE中静态实例管理方式
ACE中的很多类使用了单例模式,为了便于管理单例对象,ACE使用了一个组件——ACE_Framework_Component来专门管理。
我们以ACE_Reactor这个单例类的创建和释放为例。
1、Reactor.cpp中,包括了类的创建释放。其中,单例模式的接口有两个instance函数提供——有参和无参。
首先来看无参instance:
1 ACE_Reactor * 2 ACE_Reactor::instance (void) 3 { 4 ACE_TRACE ("ACE_Reactor::instance"); 5 6 if (ACE_Reactor::reactor_ == 0) 7 { 8 // Perform Double-Checked Locking Optimization. 9 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, 10 *ACE_Static_Object_Lock::instance (), 0)); 11 12 if (ACE_Reactor::reactor_ == 0) 13 { 14 ACE_NEW_RETURN (ACE_Reactor::reactor_, 15 ACE_Reactor, 16 0); 17 ACE_Reactor::delete_reactor_ = true; //由于动态生成了一个ACE_Reactor对象,所以将delete_reactor_字段设为true 18 ACE_REGISTER_FRAMEWORK_COMPONENT(ACE_Reactor, ACE_Reactor::reactor_) //将Singleton对象注册到一个统一的管理器中 19 } 20 } 21 return ACE_Reactor::reactor_; 22 }
这里使用了经典的双检锁的实现方式。ACE_MT宏会根据系统是否启用多线程来采取相应的操作:如果系统没有启用多线程,那么它的定义为空,这样可以避免给单线程系统添加额外的负担;否则它会执行宏定义的操作,实现方式如下:
1 # if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) 2 # define ACE_MT(X) X 3 # else 4 # define ACE_MT(X) 5 # endif /* ACE_MT_SAFE */
有参instance:
1 ACE_Reactor * 2 ACE_Reactor::instance (ACE_Reactor *r, bool delete_reactor) 3 { 4 ACE_TRACE ("ACE_Reactor::instance"); 5 6 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, 7 *ACE_Static_Object_Lock::instance (), 0)); 8 ACE_Reactor *t = ACE_Reactor::reactor_; 9 ACE_Reactor::delete_reactor_ = delete_reactor; 10 11 ACE_Reactor::reactor_ = r; 12 13 // We can't register the Reactor singleton as a framework component twice. 14 // Therefore we test to see if we had an existing reactor instance, which 15 // if so means it must have already been registered. 16 if (t == 0) 17 ACE_REGISTER_FRAMEWORK_COMPONENT(ACE_Reactor, ACE_Reactor::reactor_); 18 19 return t; 20 }
这里是为了保证灵活性,我们可以创建一个需要的定制reactor并传入ACE_Reactor。具体使用方式如下:
1 Ace_Reactor_Impl *impl=0; 2 impl = new ACE_Select_Reactor(); 3 ACE_Reactor *reactor=0; 4 reactor=new ACE_Reactor(impl); 5 ACE_Reactor::instance(reactor);
2、生成了单例对象后,通过宏ACE_REGISTER_FRAMEWORK_COMPONENT将其注册到ACE_Framework_Component中,其定义如下:
/// This macro should be called in the instance() method /// of the Concrete class that will be managed. Along /// with the appropriate template instantiation. #define ACE_REGISTER_FRAMEWORK_COMPONENT(CLASS, INSTANCE) \ ACE_Framework_Repository::instance ()->register_component \ (new ACE_Framework_Component_T<CLASS> (INSTANCE));
可以看到其将Singleton对象封装进了一个接口类ACE_Framework_Component_T并注册到ACE_Framework_Repository中进行统一管理。
3、下面来看一下ACE_Framework_Component_T类的实现。
ACE_Framework_Component_T.h
1 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 2 3 /** 4 * @class ACE_Framework_Component_T 5 * 6 * @brief This class inherits the interface of the abstract 7 * ACE_Framework_Component class and is instantiated with the 8 * implementation of the concrete component class @c class Concrete. 9 * 10 * This design is similar to the Adapter and Decorator patterns 11 * from the ``Gang of Four'' book. Note that @c class Concrete 12 * need not inherit from a common class since ACE_Framework_Component 13 * provides the uniform virtual interface! (implementation based on 14 * ACE_Dumpable_Adapter in <ace/Dump_T.h>. 15 */ 16 template <class Concrete> 17 class ACE_Framework_Component_T : public ACE_Framework_Component 18 { 19 public: 20 // = Initialization and termination methods. 21 22 /// Constructor. 23 ACE_Framework_Component_T (Concrete *concrete); 24 25 /// Destructor. 26 ~ACE_Framework_Component_T (void); 27 28 /// Close the contained singleton. 29 void close_singleton (void); 30 31 ACE_ALLOC_HOOK_DECLARE; 32 }; 33 34 ACE_END_VERSIONED_NAMESPACE_DECL
ACE_Framework_Component_T.cpp
1 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 2 3 template <class Concrete> 4 ACE_Framework_Component_T<Concrete>::ACE_Framework_Component_T (Concrete *concrete) 5 : ACE_Framework_Component ((void *) concrete, concrete->dll_name (), concrete->name ()) 6 { 7 ACE_TRACE ("ACE_Framework_Component_T<Concrete>::ctor"); 8 } 9 10 template <class Concrete> 11 ACE_Framework_Component_T<Concrete>::~ACE_Framework_Component_T (void) 12 { 13 ACE_TRACE ("ACE_Framework_Component_T<Concrete>::~ACE_Framework_Component_T"); 14 Concrete::close_singleton (); 15 } 16 17 ACE_ALLOC_HOOK_DEFINE_Tt(ACE_Framework_Component_T) 18 19 template <class Concrete> void 20 ACE_Framework_Component_T<Concrete>::close_singleton (void) 21 { 22 ACE_TRACE ("ACE_Framework_Component_T<Concrete>::close_singleton"); 23 Concrete::close_singleton (); 24 } 25 26 ACE_END_VERSIONED_NAMESPACE_DECL
可以看到该类主要有构造函数、析构函数、和close_singleton。其中close_singleton会调用模板concrete即传入的单例对象的静态close_singleton函数。
1 void 2 ACE_Reactor::close_singleton (void) 3 { 4 ACE_TRACE ("ACE_Reactor::close_singleton"); 5 6 ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, 7 *ACE_Static_Object_Lock::instance ())); 8 9 if (ACE_Reactor::delete_reactor_) 10 { 11 delete ACE_Reactor::reactor_; 12 ACE_Reactor::reactor_ = 0; 13 ACE_Reactor::delete_reactor_ = false; 14 } 15 }
4、对于ACE_Framework_Repository,register_component函数首先会遍历component查找该singleton对象是否已存在,而后会将其加入列表。
1 int 2 ACE_Framework_Repository::register_component (ACE_Framework_Component *fc) 3 { 4 ACE_TRACE ("ACE_Framework_Repository::register_component"); 5 ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1); 6 int i; 7 8 // Check to see if it's already registered 9 for (i = 0; i < this->current_size_; i++) 10 if (this->component_vector_[i] && 11 fc->this_ == this->component_vector_[i]->this_) 12 { 13 ACELIB_ERROR_RETURN ((LM_ERROR, 14 "AFR::register_component: error, compenent already registered\n"), 15 -1); 16 } 17 18 if (i < this->total_size_) 19 { 20 this->component_vector_[i] = fc; 21 ++this->current_size_; 22 return 0; 23 } 24 25 return -1; 26 }
5、补充:对于ACE_Framework_Component_T有很有意思的地方,在声明中有这样一个宏:ACE_ALLOC_HOOK_DECLARE,其定义如下:
1 # if defined (ACE_HAS_ALLOC_HOOKS) 2 # define ACE_ALLOC_HOOK_DECLARE \ 3 void *operator new (size_t bytes); \ 4 void *operator new (size_t bytes, void *ptr); \ 5 void *operator new (size_t bytes, const std::nothrow_t &) throw (); \ 6 void operator delete (void *ptr); \ 7 void operator delete (void *ptr, const std::nothrow_t &); \ 8 void *operator new[] (size_t size); \ 9 void operator delete[] (void *ptr); \ 10 void *operator new[] (size_t size, const std::nothrow_t &) throw (); \ 11 void operator delete[] (void *ptr, const std::nothrow_t &)
定义中有宏:ACE_ALLOC_HOOK_DEFINE_Tt(ACE_Framework_Component_T):
1 # if defined (ACE_HAS_ALLOC_HOOKS) 2 …… 3 # define ACE_ALLOC_HOOK_DEFINE_Tt(CLASS) \ 4 ACE_GENERIC_ALLOCS (ACE_ALLOC_HOOK_HELPER_Tt, CLASS)
1 # define ACE_GENERIC_ALLOCS(MAKE_PREFIX, CLASS) \ 2 MAKE_PREFIX (void *, CLASS)::operator new (size_t bytes) \ 3 { \ 4 void *const ptr = ACE_Allocator::instance ()->malloc (bytes); \ 5 if (ptr == 0) \ 6 throw std::bad_alloc (); \ 7 return ptr; \ 8 } \ 9 MAKE_PREFIX (void *, CLASS)::operator new (size_t, void *ptr) { return ptr; }\ 10 MAKE_PREFIX (void *, CLASS)::operator new (size_t bytes, \ 11 const std::nothrow_t &) throw () \ 12 { return ACE_Allocator::instance ()->malloc (bytes); } \ 13 MAKE_PREFIX (void, CLASS)::operator delete (void *ptr) \ 14 { if (ptr) ACE_Allocator::instance ()->free (ptr); } \ 15 MAKE_PREFIX (void, CLASS)::operator delete (void *ptr, \ 16 const std::nothrow_t &) \ 17 { if (ptr) ACE_Allocator::instance ()->free (ptr); } \ 18 MAKE_PREFIX (void *, CLASS)::operator new[] (size_t size) \ 19 { \ 20 void *const ptr = ACE_Allocator::instance ()->malloc (size); \ 21 if (ptr == 0) \ 22 throw std::bad_alloc (); \ 23 return ptr; \ 24 } \ 25 MAKE_PREFIX (void, CLASS)::operator delete[] (void *ptr) \ 26 { if (ptr) ACE_Allocator::instance ()->free (ptr); } \ 27 MAKE_PREFIX (void *, CLASS)::operator new[] (size_t size, \ 28 const std::nothrow_t &) throw ()\ 29 { return ACE_Allocator::instance ()->malloc (size); } \ 30 MAKE_PREFIX (void, CLASS)::operator delete[] (void *ptr, \ 31 const std::nothrow_t &) \ 32 { if (ptr) ACE_Allocator::instance ()->free (ptr); }
而如果宏定义ACE_HAS_ALLOC_HOOKS未定义,则全部宏为空。
1 # else 2 # define ACE_ALLOC_HOOK_DECLARE struct Ace_ {} /* Just need a dummy... */ 3 # define ACE_ALLOC_HOOK_DEFINE(CLASS) 4 # define ACE_ALLOC_HOOK_DEFINE_Tt(CLASS) 5 # define ACE_ALLOC_HOOK_DEFINE_Tc(CLASS) 6 # define ACE_ALLOC_HOOK_DEFINE_Tcc(CLASS) 7 # define ACE_ALLOC_HOOK_DEFINE_Tccc(CLASS) 8 # define ACE_ALLOC_HOOK_DEFINE_Tccct(CLASS) 9 # define ACE_ALLOC_HOOK_DEFINE_Tc4(CLASS) 10 # define ACE_ALLOC_HOOK_DEFINE_Tc5(CLASS) 11 # define ACE_ALLOC_HOOK_DEFINE_Tc6(CLASS) 12 # define ACE_ALLOC_HOOK_DEFINE_Tc7(CLASS) 13 # define ACE_ALLOC_HOOK_DEFINE_Ty(CLASS) 14 # define ACE_ALLOC_HOOK_DEFINE_Tyc(CLASS) 15 # define ACE_ALLOC_HOOK_DEFINE_Tycc(CLASS) 16 # define ACE_ALLOC_HOOK_DEFINE_Tcy(CLASS) 17 # define ACE_ALLOC_HOOK_DEFINE_Tcyc(CLASS) 18 # define ACE_ALLOC_HOOK_DEFINE_Tca(CLASS) 19 # define ACE_ALLOC_HOOK_DEFINE_Tco(CLASS) 20 # define ACE_ALLOC_HOOK_DEFINE_Tcoccc(CLASS) 21 # define ACE_ALLOC_HOOK_DEFINE_Tcs(CLASS) 22 # define ACE_ALLOC_HOOK_DEFINE_Tmcc(CLASS) 23 # endif /* ACE_HAS_ALLOC_HOOKS */
这里可以在编译时选择是否添加内存管理钩子hook,通过ACE框架来管理内存,便于对系统进行管理与调试。