Threading mess when exiting a multithreaded ORBit2 application

Jules Colding <[email protected]>
Newsgroups gmane.comp.gnome.orbit.general
Message-ID <[email protected]>
Hi,

Either I am confused/stupid or I am seeing threading mess when Evolution
exists. 

Foreword: 
   I am writing a shared library that is to be used by Evolution 2.4.
This library are using ORBit2. The library invokes CORBA_ORB_init() as
any good CORBA app should do.

Problem:
   shutdown_orb() is being invoked twice when Evolution exits. This
leads to obvious problems of having a hard time freeing already freed
objects. shutdown_orb() is defined as the exit function with "g_atexit
(shutdown_orb)". In short:


	1) shutdown_orb() should not be invoked twice.

	2) There should only be one instance of the static mutex
"init_level_mutex" but there are two.


Output and debug patch below.

Any ideas?
  jules



Diagnostics: 
   The problem is visualized by the following output. shutdown_orb( is
clearly invoked twice:


** BRUTUS_DEBUG - camel-brutus-store.c@985:
 ** ORBit2 DEBUG - corba-orb.c@295: shutdown_orb() before locking
 ** ORBit2 DEBUG - corba-orb.c@299: shutdown_orb() after locking

 ** ORBit2 DEBUG - Address of init_level_mutex is 0x2aaaae6c05a0
 ** ORBit2 DEBUG - corba-orb.c@1245: CORBA_ORB_destroy()

** BRUTUS_DEBUG - camel-brutus-store.c@170: ORB shutdown in progress
 ** ORBit2 DEBUG - corba-orb.c@295: shutdown_orb() before locking
 ** ORBit2 DEBUG - corba-orb.c@299: shutdown_orb() after locking

 ** ORBit2 DEBUG - Address of init_level_mutex is 0x2aaaad7055a0
 ** ORBit2 DEBUG - corba-orb.c@1245: CORBA_ORB_destroy()

The above output is produced with the following patch to CVS HEAD:

Index: corba-orb.c
===================================================================
RCS file: /cvs/gnome/ORBit2/src/orb/orb-core/corba-orb.c,v
retrieving revision 1.115
diff -u -p -r1.115 corba-orb.c
--- corba-orb.c	8 Aug 2005 12:48:24 -0000	1.115
+++ corba-orb.c	19 Sep 2005 12:07:18 -0000
@@ -30,6 +30,10 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL,
 		     LPVOID    lpvReserved);
 #endif
 
+#undef d
+#define d(_str_) G_STMT_START { g_print(" ** ORBit2 DEBUG - %s@%d: %s\n", __FILE__, __LINE__, _str_); } G_STMT_END
+
+
 /*
  * Command line option handling.
  */
@@ -274,6 +278,7 @@ ORBit_setup_debug_flags (void)
 #endif /* G_ENABLE_DEBUG */
 
 static CORBA_ORB _ORBit_orb = NULL;
+GStaticMutex     init_level_mutex = G_STATIC_MUTEX_INIT;
 static gulong    init_level = 0;
 static gboolean  atexit_shutdown = FALSE;
 
@@ -287,14 +292,25 @@ shutdown_orb (void)
 	CORBA_ORB orb;
 	CORBA_Environment ev;
 
-	if (!(orb = _ORBit_orb))
+	d("shutdown_orb() before locking");
+
+	g_static_mutex_lock (&init_level_mutex);
+
+	d("shutdown_orb() after locking");
+
+	if (!(orb = _ORBit_orb)) {
+		g_static_mutex_unlock (&init_level_mutex);
 		return;
+	}
 
 	init_level = 1; /* clobber it */
+
 	atexit_shutdown = TRUE;
 	
 	CORBA_exception_init (&ev);
 
+	g_static_mutex_unlock (&init_level_mutex);
+
 	CORBA_ORB_destroy (orb, &ev);
 	ORBit_RootObject_release (orb);
 
@@ -383,10 +399,13 @@ CORBA_ORB_init (int *argc, char **argv,
 		CORBA_ORB_release_fn
 	};
 
+	g_static_mutex_lock (&init_level_mutex);
 	init_level++;
 
-	if ((retval = _ORBit_orb))
+	if ((retval = _ORBit_orb)) {
+		g_static_mutex_unlock (&init_level_mutex);
 		return ORBit_RootObject_duplicate (retval);
+	}
 
 	/* the allocation code uses the bottom bit of any pointer */
 	g_assert (ORBIT_ALIGNOF_CORBA_DOUBLE > 2);
@@ -451,6 +470,8 @@ CORBA_ORB_init (int *argc, char **argv,
 					  ev);
 	/* FIXME, handle exceptions */ 
 
+	g_static_mutex_unlock (&init_level_mutex);
+
 	return ORBit_RootObject_duplicate (retval);
 }
 
@@ -1205,21 +1226,33 @@ CORBA_ORB_destroy (CORBA_ORB          or
 {
 	PortableServer_POA root_poa;
 
-	if (orb->life_flags & ORBit_LifeF_Destroyed)
+	g_static_mutex_lock (&init_level_mutex);
+	g_print("\n ** ORBit2 DEBUG - Address of init_level_mutex is %p\n", &init_level_mutex);
+
+	if (orb->life_flags & ORBit_LifeF_Destroyed) {
+		g_static_mutex_unlock (&init_level_mutex);
 		return;
+	}
 
 	init_level--;
+	g_assert (0 <= init_level);
 
-	if (init_level > 0)
+	if (init_level > 0) {
+		g_static_mutex_unlock (&init_level_mutex);
 		return;
+	}
+
+	d("CORBA_ORB_destroy()");
 
 	CORBA_ORB_shutdown (orb, TRUE, ev);
 
 	g_assert (_ORBit_orb == orb);
 	_ORBit_orb = NULL;
 
-	if (ev->_major)
+	if (ev->_major) {
+		g_static_mutex_unlock (&init_level_mutex);
 		return;
+	}
 
 	root_poa = g_ptr_array_index (orb->adaptors, 0);
 	if (root_poa &&
@@ -1297,6 +1330,8 @@ CORBA_ORB_destroy (CORBA_ORB          or
 	if (ORBit_RootObject_shutdown (!atexit_shutdown))
 		CORBA_exception_set_system (
 			ev, ex_CORBA_FREE_MEM, CORBA_COMPLETED_NO);
+
+	g_static_mutex_unlock (&init_level_mutex);
 }
 
 CORBA_Policy
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.