Threading mess when exiting a multithreaded ORBit2 application



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




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]