[omniORB] Update : OmniORB3.01 - Reducing memory leaks - patch 1

Jeroen.Dobbelaere@MMR.be Jeroen.Dobbelaere@MMR.be
Fri, 15 Sep 2000 17:15:53 +0100


This message is in MIME format. Since your mail reader does not understand
this format, some or all of this message may not be legible.

------_=_NextPart_000_01C01F30.38DAD660
Content-Type: text/plain;
	charset="ISO-8859-1"

Hi,

here is a version of patch1 without using STL.

Greetings,
--
Jeroen Dobbelaere
Software Design Engineer
Micro-Matic Research <http://www.mmr.be>


 <<patch1-no-stl.patch>> 

------_=_NextPart_000_01C01F30.38DAD660
Content-Type: application/octet-stream;
	name="patch1-no-stl.patch"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="patch1-no-stl.patch"

*** omni/src/lib/OmniORB2/dynamic/typecode.cc	Thu Jul 13 16:26:02 2000
--- omni_test/src/lib/OmniORB2/dynamic/typecode.cc	Fri Sep 15 17:06:47 =
2000
***************
*** 209,218 ****
--- 209,316 ----
  #ifndef NEED_DUMMY_RETURN
  #define NEED_DUMMY_RETURN
  #endif
  #endif
 =20
+ // class that tracks the created (static) exceptions, needed for =
cleanup later...
+ // provide a Container without using stl (for compilers which don't =
support it)
+ #define TTPTR_CONTAINER_CHUNKSIZE (1024)
+=20
+ class TrackTypeCode_ptr_Container
+ {
+ public:
+   struct Chunk
+   {
+     CORBA::TypeCode_ptr     m_data[TTPTR_CONTAINER_CHUNKSIZE];
+     Chunk*           m_previous;
+=20
+     Chunk(Chunk* prev) : m_previous(prev) { }
+   };
+=20
+ public:
+   TrackTypeCode_ptr_Container()
+   {
+     m_last =3D 0;
+     m_entry =3D 0;
+   }
+=20
+   ~TrackTypeCode_ptr_Container()
+   {
+     Chunk* p =3D m_last;
+     while(p !=3D 0)
+       {
+ 	Chunk* prev =3D p->m_previous;
+ 	delete p;
+ 	p =3D prev;
+       }
+   }
+=20
+   void reverse_delete()
+   {
+     // should only be called once
+=20
+     unsigned long i =3D m_entry;
+     Chunk* p =3D m_last;
+     while(p !=3D 0)
+       {
+ 	while(i !=3D 0)
+ 	  {
+ 	    --i;
+ 	    delete p->m_data[i];
+ 	  }
+ =09
+ 	i=3DTTPTR_CONTAINER_CHUNKSIZE;
+=20
+ 	Chunk* prev =3D p->m_previous;
+=20
+ 	delete p;
+ 	p =3D prev;
+       }
+    =20
+     // and reinitialise (just for safety)
+     m_last =3D 0;
+     m_entry =3D 0;
+   }
+=20
+   void push_back(CORBA::TypeCode_ptr p)
+   {
+     if((m_last =3D=3D 0) || (m_entry =3D=3D =
TTPTR_CONTAINER_CHUNKSIZE))
+       {
+ 	m_last =3Dnew Chunk(m_last);
+ 	m_entry =3D 0;
+       }
+=20
+     m_last->m_data[m_entry] =3D p;
+     ++m_entry;
+   }
+=20
+ private:
+   Chunk*        m_last;
+   unsigned long m_entry; // next entry to be filled.
+ };
+=20
+=20
+=20
+ class TrackTypeCode_ptr
+ {
+ public:
+   TrackTypeCode_ptr() {}
+   ~TrackTypeCode_ptr() {}
+=20
+   void attach(const CORBA::TypeCode_ptr& rhs) { =
m_table.push_back(rhs); }
+=20
+   void delete_all()=20
+   {
+     m_table.reverse_delete();
+   }
+=20
+ private:
+   TrackTypeCode_ptr_Container m_table;
+ };
+=20
+=20
+=20
 =20
  CORBA::TypeCode::~TypeCode() {
    pd_magic =3D 0;
  }
 =20
***************
*** 330,343 ****
    if (CORBA::is_nil(t))  return t;
    return TypeCode_collector::duplicateRef(ToTcBase(t));
  }
 =20
 =20
  CORBA::TypeCode_ptr
  CORBA::TypeCode::_nil()
  {
-   static TypeCode* _the_nil_ptr =3D 0;
    if( !_the_nil_ptr ) {
      omni::nilRefLock().lock();
      if( !_the_nil_ptr )  _the_nil_ptr =3D new TypeCode;
      omni::nilRefLock().unlock();
    }
--- 428,456 ----
    if (CORBA::is_nil(t))  return t;
    return TypeCode_collector::duplicateRef(ToTcBase(t));
  }
 =20
 =20
+ // move _the_nil_ptr outside of CORBA::TypeCode::_nil(), so that it =
can get destructed when needed
+ // _the_nil_ptr stays only visible inside this file
+ static CORBA::TypeCode* _the_nil_ptr =3D 0;
+=20
+ // and provide a class, so that this nil pointer can be destructed =
when the program ends
+ class CleanupTypecodeNil
+ {
+ public:
+   ~CleanupTypecodeNil() { delete _the_nil_ptr; _the_nil_ptr=3D0; }
+=20
+ private:
+   static CleanupTypecodeNil local_object;
+ };
+ CleanupTypecodeNil CleanupTypecodeNil::local_object;
+=20
+=20
  CORBA::TypeCode_ptr
  CORBA::TypeCode::_nil()
  {
    if( !_the_nil_ptr ) {
      omni::nilRefLock().lock();
      if( !_the_nil_ptr )  _the_nil_ptr =3D new TypeCode;
      omni::nilRefLock().unlock();
    }
***************
*** 512,521 ****
--- 625,637 ----
  // of the typecode functionnality it is important to ensure
  // that any statically initialised data is properly constructed.
 =20
  static void check_static_data_is_initialised();
 =20
+ // track TypeCode_ptr's, for later cleanup (in reversed order)
+ static void track_typecode_ptr(const CORBA::TypeCode_ptr& rhs);
+=20
  CORBA::TypeCode_ptr
  CORBA::TypeCode::PR_struct_tc(const char* id, const char* name,
  			      const PR_structMember* members,
  			      ULong memberCount)
  {
***************
*** 587,606 ****
      // We duplicate the name and consume the type.
      new_members[i].name =3D CORBA::string_dup(members[i].name);
      new_members[i].type =3D members[i].type;
    }
 =20
!   return new TypeCode_except(CORBA::string_dup(id), =
CORBA::string_dup(name),
  			     new_members, memberCount);
  }
 =20
 =20
  CORBA::TypeCode_ptr
  CORBA::TypeCode::PR_interface_tc(const char* id, const char* name)
  {
    check_static_data_is_initialised();
!   return new TypeCode_objref(id, name);
  }
 =20
 =20
  CORBA::TypeCode_ptr
  CORBA::TypeCode::PR_string_tc(CORBA::ULong bound)
--- 703,737 ----
      // We duplicate the name and consume the type.
      new_members[i].name =3D CORBA::string_dup(members[i].name);
      new_members[i].type =3D members[i].type;
    }
 =20
!   // keep track of all exception objects that are created in this way
!   // they are kept in static pointers and will exist for the lifetime =
of the program
!   // and at the end, they will get destructed in reverse order
!   CORBA::TypeCode_ptr return_value =3D=20
!     new TypeCode_except(CORBA::string_dup(id), =
CORBA::string_dup(name),
  			     new_members, memberCount);
+=20
+   track_typecode_ptr(return_value);
+=20
+   return return_value;
  }
 =20
 =20
  CORBA::TypeCode_ptr
  CORBA::TypeCode::PR_interface_tc(const char* id, const char* name)
  {
    check_static_data_is_initialised();
!=20
!   // keep track the generated interface pointers, they will exist for =
the lifetime of the program
!   // and at the end, they will get destructed in reverse order
!   CORBA::TypeCode_ptr return_value =3D new TypeCode_objref(id, name);
!=20
!   track_typecode_ptr(return_value);
!=20
!   return return_value;
  }
 =20
 =20
  CORBA::TypeCode_ptr
  CORBA::TypeCode::PR_string_tc(CORBA::ULong bound)
***************
*** 5322,5334 ****
  // also generate new typecodes. This is used to ensure that all
  // necassary infrastructure is properly constructed before it is
  // accessed by the stubs. This is necassary because the compiler
  // does not specify the order of initialisation.
  //
  static void check_static_data_is_initialised()
  {
!   static int is_initialised =3D 0;
 =20
    if( is_initialised )  return;
 =20
    is_initialised =3D 1;
 =20
--- 5453,5470 ----
  // also generate new typecodes. This is used to ensure that all
  // necassary infrastructure is properly constructed before it is
  // accessed by the stubs. This is necassary because the compiler
  // does not specify the order of initialisation.
  //
+=20
+ // is_initialised has been -- moved out of =
check_static_data_is_initialised
+ // so that it can be used by remove_static_data for a nice cleanup
+ static int is_initialised =3D 0;
+=20
  static void check_static_data_is_initialised()
  {
!   // static int is_initialised =3D 0;
 =20
    if( is_initialised )  return;
 =20
    is_initialised =3D 1;
 =20
***************
*** 5371,5386 ****
--- 5507,5630 ----
     =20
      CORBA::_tc_NamedValue =3D =
CORBA::TypeCode::PR_struct_tc("IDL:omg.org/CORBA/NamedValue:1.0", =
"NamedValue",nvMembers, 4);
    }
  }
 =20
+ // remove_static_data : remove the data in reverse order
+ // watch out ! some of the objects were already consumed by other =
created objectes !!
+ static void remove_static_data()
+ {
+   if(is_initialised=3D=3D0)
+     return;
+=20
+   // objects which are already delete by the exception cleanup
+   CORBA::_tc_Object=3DNULL;
+   CORBA::_tc_ulong=3DNULL;
+   CORBA::_tc_ushort=3DNULL;
+=20
+   // can cause conflicts with tc_any and tc_long
+   delete  CORBA::_tc_NamedValue;
+   CORBA::_tc_NamedValue =3D NULL;
+=20
+   // deletion of _tc_NamedValue also deletes :
+   CORBA::_tc_any =3D NULL;
+   CORBA::_tc_long =3D NULL;
+=20
+   //remove types
+   delete CORBA::_tc_string;
+   CORBA::_tc_string=3DNULL;
+  =20
+   delete CORBA::_tc_Object;
+   CORBA::_tc_Object=3DNULL;
+  =20
+   delete CORBA::_tc_Principal;
+   CORBA::_tc_Principal=3DNULL;
+  =20
+   delete CORBA::_tc_TypeCode;
+   CORBA::_tc_TypeCode=3DNULL;
+  =20
+   delete CORBA::_tc_any;
+   CORBA::_tc_any=3DNULL;
+  =20
+   delete CORBA::_tc_octet;
+   CORBA::_tc_octet=3DNULL;
+=20
+   delete CORBA::_tc_char;
+   CORBA::_tc_char=3DNULL;
+  =20
+   delete CORBA::_tc_boolean;
+   CORBA::_tc_boolean=3DNULL;
+  =20
+   delete CORBA::_tc_double;
+   CORBA::_tc_double=3DNULL;
+=20
+   delete CORBA::_tc_float;
+   CORBA::_tc_float=3DNULL;
+  =20
+   delete CORBA::_tc_ulong;
+   CORBA::_tc_ulong=3DNULL;
+=20
+   delete CORBA::_tc_ushort;
+   CORBA::_tc_ushort=3DNULL;
+  =20
+   delete CORBA::_tc_long;
+   CORBA::_tc_long=3DNULL;
+  =20
+   delete CORBA::_tc_short;
+   CORBA::_tc_short=3DNULL;
+=20
+   delete CORBA::_tc_void;
+   CORBA::_tc_void=3DNULL;
+  =20
+   delete CORBA::_tc_null;
+   CORBA::_tc_null=3DNULL;
+  =20
+  =20
+   // remove mutexes
+   delete pd_refcount_lock;
+   pd_refcount_lock=3DNULL;
+  =20
+   delete pd_cached_paramlist_lock;
+   pd_cached_paramlist_lock=3DNULL;
+=20
+   delete aliasExpandedTc_lock;
+   aliasExpandedTc_lock=3DNULL;
+=20
+   // end of destruction
+   is_initialised =3D 0;
+ }
+=20
+=20
+=20
  // We need a singleton here as a final check, so that if no
  // stub code calls into check_static_data_is_initialised()
  // it will still be called before main().
 =20
  class TypeCodeInitialiser {
    // public just to stop brain-dead compilers complaining
  public:
    TypeCodeInitialiser() { check_static_data_is_initialised(); }
+=20
+   // when the object gets cleaned up, remove all registered interface =
pointers and exceptions
+   // then clean up the other static data
+   ~TypeCodeInitialiser() { m_trackTypeCode_ptr.delete_all(); =
remove_static_data(); }
+=20
+   // register a TypeCode_ptr for later cleanup
+   void attach(const CORBA::TypeCode_ptr& rhs)
+   {
+     m_trackTypeCode_ptr.attach(rhs);
+   }
+=20
    static TypeCodeInitialiser typecode_initialiser;
+=20
+ private:
+   TrackTypeCode_ptr m_trackTypeCode_ptr;
  };
+=20
  TypeCodeInitialiser TypeCodeInitialiser::typecode_initialiser;
+=20
+=20
+ static void track_typecode_ptr(const CORBA::TypeCode_ptr& rhs)
+ {
+   TypeCodeInitialiser::typecode_initialiser.attach(rhs);
+ }
+=20

------_=_NextPart_000_01C01F30.38DAD660--