Go to the documentation of this file.00001
00002
00003 #include "orbsvcs/Notify/Refcountable.h"
00004 #include "tao/debug.h"
00005 #include "ace/Log_Msg.h"
00006
00007 #include "ace/Guard_T.h"
00008
00009 ACE_RCSID(Notify, TAO_Notify_Refcountable, "$Id: Refcountable.cpp 71526 2006-03-14 06:14:35Z jtc $")
00010
00011 #if ( TAO_NOTIFY_REFCOUNT_DIAGNOSTICS != 0 )
00012
00013 #include <map>
00014 #include <string>
00015 #include <typeinfo.h>
00016
00017 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 class TAO_Notify_Tracker
00030 {
00031 public:
00032 struct Entry
00033 {
00034 TAO_Notify_Refcountable* obj;
00035 std::string class_name;
00036 };
00037
00038 static TAO_Notify_Tracker& get_instance();
00039
00040 void add( TAO_Notify_Refcountable* p );
00041
00042 void remove( const TAO_Notify_Refcountable* p );
00043
00044 Entry find( const TAO_Notify_Refcountable* p ) const;
00045
00046 void dump( const char* title = 0 );
00047
00048 private:
00049 TAO_Notify_Tracker();
00050 ~TAO_Notify_Tracker();
00051
00052 friend class std::auto_ptr< TAO_Notify_Tracker >;
00053 static std::auto_ptr< TAO_Notify_Tracker > s_instance;
00054 mutable TAO_SYNCH_MUTEX lock_;
00055 typedef std::map<int, Entry> EntityMap;
00056 EntityMap map_;
00057 int id_counter_;
00058 int last_dump_count_;
00059 };
00060
00061 void
00062 TAO_Notify_Refcountable::diagnostic_dump( const char* title )
00063 {
00064 TAO_Notify_Tracker::get_instance().dump( title );
00065 }
00066
00067 #endif
00068
00069
00070 TAO_Notify_Refcountable::TAO_Notify_Refcountable (void)
00071 {
00072 }
00073
00074 TAO_Notify_Refcountable::~TAO_Notify_Refcountable ()
00075 {
00076 #if ( TAO_NOTIFY_REFCOUNT_DIAGNOSTICS != 0 )
00077 TAO_Notify_Tracker::Entry e = TAO_Notify_Tracker::get_instance().find( this );
00078 if ( e.obj != 0 )
00079 {
00080 ACE_DEBUG ((LM_DEBUG,"object:%x %s(%d) with refcount:%d destroyed incorrectly.\n",
00081 e.obj, e.class_name, e.obj->ref_id_, e.obj->refcount_.value() ));
00082
00083 if ( e.obj != this || e.obj->ref_id_ != this->ref_id_ )
00084 {
00085 ACE_DEBUG ((LM_DEBUG, " with an ID mismatch %x->%d != %x->%d!\n",
00086 this, ref_id_, e.obj, e.obj->ref_id_));
00087 }
00088 TAO_Notify_Tracker::get_instance().remove( this );
00089 }
00090 #endif
00091 CORBA::ULong refcount = this->refcount_.value();
00092 ACE_ASSERT( refcount == 0 );
00093 ACE_UNUSED_ARG(refcount);
00094 }
00095
00096
00097 CORBA::ULong
00098 TAO_Notify_Refcountable::_incr_refcnt (void)
00099 {
00100 CORBA::Long refcount = ++this->refcount_;
00101 if (TAO_debug_level > 1 )
00102 {
00103 ACE_DEBUG ((LM_DEBUG,"object:%x incr refcount = %d\n", this, refcount ));
00104 }
00105 #if ( TAO_NOTIFY_REFCOUNT_DIAGNOSTICS != 0 )
00106
00107
00108
00109 if ( refcount == 1 )
00110 {
00111 TAO_Notify_Tracker::get_instance().add( this );
00112 }
00113 #endif
00114 return refcount;
00115 }
00116
00117 CORBA::ULong
00118 TAO_Notify_Refcountable::_decr_refcnt (void)
00119 {
00120 CORBA::Long refcount = --this->refcount_;
00121
00122 if (TAO_debug_level > 1 )
00123 {
00124 ACE_DEBUG ((LM_DEBUG,"object:%x decr refcount = %d\n", this, refcount ));
00125 }
00126
00127 ACE_ASSERT(refcount >= 0);
00128
00129 if (refcount == 0)
00130 {
00131 #if ( USE_TAO_NOTIFY_TRACKER != 0 )
00132 TAO_Notify_Tracker::get_instance().remove( this );
00133 #endif
00134 this->release ();
00135 }
00136 return refcount;
00137 }
00138
00139 #if ( TAO_NOTIFY_REFCOUNT_DIAGNOSTICS != 0 )
00140
00141 std::auto_ptr< TAO_Notify_Tracker > TAO_Notify_Tracker::s_instance;
00142
00143 TAO_Notify_Tracker::TAO_Notify_Tracker()
00144 : id_counter_(0)
00145 , last_dump_count_(0)
00146 {
00147 }
00148
00149
00150 TAO_Notify_Tracker::~TAO_Notify_Tracker()
00151 {
00152 dump( "destruction" );
00153 }
00154
00155
00156 void
00157 TAO_Notify_Tracker::dump( const char* title )
00158 {
00159 ACE_Guard<TAO_SYNCH_MUTEX> grd(this->lock_);
00160
00161 ACE_DEBUG ((LM_DEBUG,"\nTAO_Notify_Tracker: %s\n", (title ? title : "dump")));
00162
00163 EntityMap::const_iterator iter( map_.begin() );
00164 while ( iter != map_.end() )
00165 {
00166 ACE_DEBUG ((LM_DEBUG,"object:%x %s(%d) with refcount:%d.\n",
00167 iter->second.obj, iter->second.class_name, iter->first, iter->second.obj->refcount_.value() ));
00168 iter++;
00169 }
00170
00171 EntityMap::size_type current_count = map_.size();
00172 int diff = ( current_count - last_dump_count_ );
00173 ACE_DEBUG ((LM_DEBUG,"Count: %u\nDifference: %+d\n", current_count, diff ));
00174 last_dump_count_ = current_count;
00175 }
00176
00177
00178 TAO_Notify_Tracker&
00179 TAO_Notify_Tracker::get_instance()
00180 {
00181 if ( s_instance.get() == 0 )
00182 {
00183 s_instance.reset( new TAO_Notify_Tracker );
00184 }
00185 return *s_instance;
00186 }
00187
00188
00189 void
00190 TAO_Notify_Tracker::add( TAO_Notify_Refcountable* p )
00191 {
00192 if ( p == 0 ) return;
00193
00194 ACE_Guard<TAO_SYNCH_MUTEX> grd(this->lock_);
00195 int id = ++id_counter_;
00196
00197 Entry e = { p, typeid(*p).name() };
00198 std::pair< EntityMap::iterator, bool > result =
00199 map_.insert( std::make_pair( id, e ) );
00200 EntityMap::iterator& it = result.first;
00201 if ( result.second == false )
00202 {
00203 ACE_DEBUG ((LM_DEBUG,"object:%x %s(%d) added twice.\n",
00204 it->second.obj, it->second.class_name.c_str(), it->first ));
00205 }
00206 else
00207 {
00208 p->ref_id_ = id;
00209 }
00210 }
00211
00212
00213 void
00214 TAO_Notify_Tracker::remove( const TAO_Notify_Refcountable* p )
00215 {
00216 if ( p == 0 ) return;
00217
00218 ACE_Guard<TAO_SYNCH_MUTEX> grd(this->lock_);
00219 int ref_id = p->ref_id_;
00220 EntityMap::iterator iter( map_.find( ref_id ) );
00221 if ( iter == map_.end() )
00222 {
00223 const char* class_name = typeid(*iter->second.obj).name();
00224 ACE_DEBUG ((LM_DEBUG,"object:%x %s(%d) not found.\n",
00225 p, class_name, ref_id ));
00226 }
00227 else
00228 {
00229 map_.erase( iter );
00230 }
00231 }
00232
00233
00234 TAO_Notify_Tracker::Entry
00235 TAO_Notify_Tracker::find( const TAO_Notify_Refcountable* p ) const
00236 {
00237 Entry e = { 0, "" };
00238 if ( p == 0 ) return e;
00239
00240 ACE_Guard<TAO_SYNCH_MUTEX> grd(this->lock_);
00241 int ref_id = p->ref_id_;
00242 EntityMap::const_iterator iter( map_.find( ref_id ) );
00243 if ( iter != map_.end() )
00244 {
00245 return iter->second;
00246 }
00247 return e;
00248 }
00249
00250 TAO_END_VERSIONED_NAMESPACE_DECL
00251
00252 #endif