module.h

Go to the documentation of this file.
00001 00004 /* 00005 * Copyright © 2000-2002 Sofus Mortensen, Paul Hollingsworth, Michael Geddes, Mikael Lindgren 00006 * 00007 * This material is provided "as is", with absolutely no warranty 00008 * expressed or implied. Any use is at your own risk. Permission to 00009 * use or copy this software for any purpose is hereby granted without 00010 * fee, provided the above notices are retained on all copies. 00011 * Permission to modify the code and to distribute modified code is 00012 * granted, provided the above notices are retained, and a notice that 00013 * the code was modified is included with the above copyright notice. 00014 * 00015 * This header is part of comet. 00016 * http://www.lambdasoft.dk/comet 00017 */ 00018 00019 #ifndef COMET_MODULE_H 00020 #define COMET_MODULE_H 00021 00022 #include <vector> 00023 #include <comet/config.h> 00024 #include <comet/tstring.h> 00025 #include <comet/threading.h> 00026 00027 namespace comet { 00028 00032 namespace impl { 00036 struct cmd_t 00037 { 00038 virtual void cmd() = 0; 00039 cmd_t() {} 00040 private: 00041 cmd_t(const cmd_t&); 00042 cmd_t& operator=(const cmd_t&); 00043 }; 00044 00049 template<typename T> 00050 struct itf_releaser_t : public cmd_t 00051 { 00052 void cmd() { IUnknown *p = p_; p_=NULL; p->Release(); } 00053 itf_releaser_t(T *&p) :p_(p) { } 00054 private: 00055 T *&p_; 00056 itf_releaser_t(const itf_releaser_t&); 00057 itf_releaser_t& operator=(const itf_releaser_t&); 00058 }; 00059 00060 template<typename T> 00061 cmd_t *create_itf_releaser( T *&p) 00062 { 00063 return new itf_releaser_t<T>(p); 00064 } 00065 00069 template<typename T> 00070 struct pointer_deleter_t : public cmd_t 00071 { 00072 void cmd() { T *p = p_; p_=NULL; delete p;} 00073 pointer_deleter_t(T *&p) :p_(p) { } 00074 private: 00075 T *&p_; 00076 pointer_deleter_t(const pointer_deleter_t&); 00077 pointer_deleter_t& operator=(const pointer_deleter_t&); 00078 }; 00079 00083 template<typename T> 00084 struct object_disposer_t : public cmd_t 00085 { 00086 void cmd() { p_->object_dispose(); } 00087 object_disposer_t( T*p) : p_(p) {} 00088 private: 00089 T *p_; 00090 object_disposer_t(const object_disposer_t &); 00091 object_disposer_t &operator=(const object_disposer_t &); 00092 }; 00093 } 00095 00101 template<typename T> 00102 impl::cmd_t *create_pointer_deleter( T *&p) 00103 { 00104 return new impl::pointer_deleter_t<T>(p); 00105 } 00107 00114 template<typename T> 00115 impl::cmd_t *create_interface_releaser( T *&p) 00116 { 00117 return new impl::itf_releaser_t<T>(p); 00118 } 00119 00121 00134 template<typename T> 00135 impl::cmd_t *create_object_disposer( T *p ) 00136 { 00137 return new impl::object_disposer_t<T>(p); 00138 } 00139 00141 struct module_t 00142 { 00144 00145 00146 long rc() 00147 { 00148 return rc_; 00149 } 00151 HINSTANCE instance() const 00152 { 00153 return instance_; 00154 } 00155 00157 void instance(HINSTANCE h) 00158 { 00159 instance_ = h; 00160 } 00161 00163 00167 const critical_section& cs() const 00168 { 00169 return cs_; 00170 } 00171 00173 00175 00176 00178 void lock() 00179 { 00180 if (InterlockedIncrement(&rc_) == 1 && shutdown_event_ != 0) 00181 { 00182 auto_cs lock(cs_); 00183 if ( shutdown_event_->is_set()) 00184 shutdown_event_->reset(); 00185 } 00186 } 00187 00189 void unlock() 00190 { 00191 if(InterlockedDecrement(&rc_)==0) 00192 { 00193 activity_ = true; 00194 if (shutdown_event_ != 0) 00195 { 00196 auto_cs lock(cs_); 00197 shutdown_event_->set(); 00198 } 00199 } 00200 } 00201 00203 void shutdown() 00204 { 00205 for (std::vector<impl::cmd_t*>::iterator it = objects_to_dispose_.begin(); it != objects_to_dispose_.end(); ++it) 00206 { 00207 (*it)->cmd(); 00208 delete *it; 00209 } 00210 objects_to_dispose_.clear(); 00211 } 00212 00214 void set_shutdown_event(event& shutdown_event) 00215 { 00216 shutdown_event_ = &shutdown_event; 00217 } 00218 00220 void clear_shutdown_event() 00221 { 00222 shutdown_event_ = 0; 00223 } 00224 00226 bool has_activity() const 00227 { 00228 return rc_ != 0 || activity_; 00229 } 00230 00232 void reset_activity_flag() 00233 { 00234 activity_ = false; 00235 } 00236 00238 void add_object_to_dispose(impl::cmd_t* p) 00239 { 00240 auto_cs lock(cs_); 00241 objects_to_dispose_.push_back(p); 00242 } 00244 00245 private: 00246 long rc_; 00247 bool activity_; 00248 event* shutdown_event_; 00249 HINSTANCE instance_; 00250 critical_section cs_; 00251 00252 module_t() : rc_(0), activity_(false), 00253 shutdown_event_(0), instance_(0) 00254 {} 00255 00256 std::vector<impl::cmd_t*> objects_to_dispose_; 00257 00258 friend module_t& module(); 00259 00260 // declare non-copyable 00261 module_t(const module_t&); 00262 module_t& operator=(const module_t&); 00263 }; 00264 00266 inline module_t& module() 00267 { 00268 static module_t m; 00269 return m; 00270 } 00272 } 00273 00274 #endif