[Bug libstdc++/29426] New: static __recursive_mutex init vs __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION

dannysmith at users dot sourceforge dot net gcc-bugzilla@gcc.gnu.org
Wed Oct 11 02:57:00 GMT 2006


The concurrence.h mutex lock/unlock changes of 13 Sept have caused
failure of all C++ testcases using std::cout on mingw32, iff  -mthreads
(enabling __gthread_active_p) option is added to RUNTESTFLAGS.

Originally, the failures were of the form"
"terminate called after throwing an instance of 'std::runtime_error'
  what():  __mutex::lock"

and resulted from the target __gthread_mutex_lock being handed an invalid
mutex.

Its a Good Thing the error checking had been turned on by the same
patchset :) 
Its a Bad Thing that I haven't been testing with -mthreads
turned on more frequently :(

This patch

2006-10-09  Benjamin Kosnik  <bkoz@redhat.com>

        PR libstdc++/29118
        * src/locale_init.cc (__get_locale_mutex): New. 
        (locale::locale): Use it.

        (locale::global): Use it.
        .  
got rid of those errors, but they were replaced by:

"terminate called after throwing an instance of 'std::runtime_error'
   what():  __recursive_mutex::lock"
            ^^^^^^^^^^^^^^^^^
(mingw32 uses __GTHREAD_MUTEX_INIT_FUNCTION)



These can be fixed by reverting this part of the 13 Sept patch

        * libsupc++/guard.cc (static_mutex): Subsume into and fixup for...
        * include/ext/concurrence.h (__recursive_mutex): ...this. 

like so:

Index: guard.cc
===================================================================
--- guard.cc    (revision 117613)
+++ guard.cc    (working copy)
@@ -42,8 +42,49 @@
 #ifdef __GTHREADS
 namespace
 {
-  // A single mutex controlling all static initializations.
-  __gnu_cxx::__recursive_mutex static_mutex;
+  // static_mutex is a single mutex controlling all static initializations.
+  // This is a static class--the need for a static initialization function
+  // to pass to __gthread_once precludes creating multiple instances, though
+  // I suppose you could achieve the same effect with a template.
+  class static_mutex
+  {
+    static __gthread_recursive_mutex_t mutex;
+
+#ifdef __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION
+    static void init();
+#endif
+
+  public:
+    static void lock();
+    static void unlock();
+  };
+
+  __gthread_recursive_mutex_t static_mutex::mutex
+#ifdef __GTHREAD_RECURSIVE_MUTEX_INIT
+  = __GTHREAD_RECURSIVE_MUTEX_INIT
+#endif
+  ;
+
+#ifdef __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION
+  void static_mutex::init()
+  {
+    __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION (&mutex);
+  }
+#endif
+
+  void static_mutex::lock()
+  {
+#ifdef __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION
+    static __gthread_once_t once = __GTHREAD_ONCE_INIT;
+    __gthread_once (&once, init);
+#endif
+    __gthread_recursive_mutex_lock (&mutex);
+  }
+
+  void static_mutex::unlock ()
+  {
+    __gthread_recursive_mutex_unlock (&mutex);
+  }
 }

 #ifndef _GLIBCXX_GUARD_TEST_AND_ACQUIRE
@@ -144,12 +185,12 @@
          bool unlock;
          mutex_wrapper (): unlock(true)
          {
-           static_mutex.lock();
+           static_mutex::lock ();
          }
          ~mutex_wrapper ()
          {
            if (unlock)
-             static_mutex.unlock();
+             static_mutex::unlock ();
          }
        } mw;

@@ -172,7 +213,7 @@
     recursion_pop (g);
 #ifdef __GTHREADS
     if (__gthread_active_p ())
-      static_mutex.unlock();
+      static_mutex::unlock ();
 #endif
   }

@@ -183,7 +224,7 @@
     _GLIBCXX_GUARD_SET_AND_RELEASE (g);
 #ifdef __GTHREADS
     if (__gthread_active_p ())
-      static_mutex.unlock();
+      static_mutex::unlock ();
 #endif
   }
 }


-- 
           Summary: static __recursive_mutex init  vs
                    __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION
           Product: gcc
           Version: 4.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: dannysmith at users dot sourceforge dot net
 GCC build triplet: i686-pc-mingw32
  GCC host triplet: i686-pc-mingw32
GCC target triplet: i686-pc-mingw32


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29426



More information about the Gcc-bugs mailing list