Prevent calling into g_cond_wait resp. g_mutex_lock/unlock directly to
authorSebastian Wilhelmi <wilhelmi@google.com>
Thu, 11 May 2006 00:08:31 +0000 (00:08 +0000)
committerSebastian Wilhelmi <wilhelmi@src.gnome.org>
Thu, 11 May 2006 00:08:31 +0000 (00:08 +0000)
2006-05-10  Sebastian Wilhelmi  <wilhelmi@google.com>

* gthread/gthread-posix.c, gthread/gthread-win32.c: Prevent
calling into g_cond_wait resp. g_mutex_lock/unlock directly to
avoid recursions into the errorcheking mutex code (and out of
principle anyway). (#335198, Chris Wilson)

ChangeLog
ChangeLog.pre-2-12
gthread/gthread-posix.c
gthread/gthread-win32.c

index 237a103..ba85e1d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2006-05-10  Sebastian Wilhelmi  <wilhelmi@google.com>
 
+       * gthread/gthread-posix.c, gthread/gthread-win32.c: Prevent
+       calling into g_cond_wait resp. g_mutex_lock/unlock directly to
+       avoid recursions into the errorcheking mutex code (and out of
+       principle anyway). (#335198, Chris Wilson)
+
        * tests/errorcheck-mutex-test.c: Adapt to GLib coding standards.
 
 2006-05-09  Sebastian Wilhelmi  <wilhelmi@google.com>
index 237a103..ba85e1d 100644 (file)
@@ -1,5 +1,10 @@
 2006-05-10  Sebastian Wilhelmi  <wilhelmi@google.com>
 
+       * gthread/gthread-posix.c, gthread/gthread-win32.c: Prevent
+       calling into g_cond_wait resp. g_mutex_lock/unlock directly to
+       avoid recursions into the errorcheking mutex code (and out of
+       principle anyway). (#335198, Chris Wilson)
+
        * tests/errorcheck-mutex-test.c: Adapt to GLib coding standards.
 
 2006-05-09  Sebastian Wilhelmi  <wilhelmi@google.com>
index 7efc2b4..633dcdb 100644 (file)
  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
  * file for a list of people on the GLib Team.  See the ChangeLog
  * files for a list of changes.  These files are distributed with
- * GLib at ftp://ftp.gtk.org/pub/gtk/. 
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
  */
 
-/* 
+/*
  * MT safe
  */
 
@@ -90,7 +90,7 @@ static gboolean posix_check_cmd_prio_warned = FALSE;
 # define pthread_key_create(a, b) pthread_keycreate (a, b)
 # define pthread_attr_init(a) pthread_attr_create (a)
 # define pthread_attr_destroy(a) pthread_attr_delete (a)
-# define pthread_create(a, b, c, d) pthread_create (a, *b, c, d) 
+# define pthread_create(a, b, c, d) pthread_create (a, *b, c, d)
 # define mutexattr_default (pthread_mutexattr_default)
 # define condattr_default (pthread_condattr_default)
 #else /* neither G_THREADS_IMPL_POSIX nor G_THREADS_IMPL_DCE are defined */
@@ -121,7 +121,7 @@ static gulong g_thread_min_stack_size = 0;
 
 #if defined(_SC_THREAD_STACK_MIN) || defined (HAVE_PRIORITIES)
 #define HAVE_G_THREAD_IMPL_INIT
-static void 
+static void
 g_thread_impl_init(void)
 {
 #ifdef _SC_THREAD_STACK_MIN
@@ -136,8 +136,8 @@ g_thread_impl_init(void)
     priority_normal_value = sched.sched_priority;
   }
 # else /* G_THREADS_IMPL_DCE */
-  posix_check_cmd (priority_normal_value = 
-                  pthread_getprio (*(pthread_t*)thread, 
+  posix_check_cmd (priority_normal_value =
+                  pthread_getprio (*(pthread_t*)thread,
                                    g_thread_priority_map [priority]));
 # endif
 #endif /* HAVE_PRIORITIES */
@@ -149,7 +149,7 @@ static GMutex *
 g_mutex_new_posix_impl (void)
 {
   GMutex *result = (GMutex *) g_new (pthread_mutex_t, 1);
-  posix_check_cmd (pthread_mutex_init ((pthread_mutex_t *) result, 
+  posix_check_cmd (pthread_mutex_init ((pthread_mutex_t *) result,
                                       mutexattr_default));
   return result;
 }
@@ -191,7 +191,7 @@ static GCond *
 g_cond_new_posix_impl (void)
 {
   GCond *result = (GCond *) g_new (pthread_cond_t, 1);
-  posix_check_cmd (pthread_cond_init ((pthread_cond_t *) result, 
+  posix_check_cmd (pthread_cond_init ((pthread_cond_t *) result,
                                      condattr_default));
   return result;
 }
@@ -199,7 +199,7 @@ g_cond_new_posix_impl (void)
 /* pthread_cond_signal, pthread_cond_broadcast and pthread_cond_wait
    can be taken directly, as signature and semantic are right, but
    without error check then!!!!, we might want to change this
-   therfore. */
+   therefore. */
 
 #define G_NSEC_PER_SEC 1000000000
 
@@ -217,27 +217,30 @@ g_cond_timed_wait_posix_impl (GCond * cond,
 
   if (!abs_time)
     {
-      g_cond_wait (cond, entered_mutex);
-      return TRUE;
+      result = pthread_cond_wait ((pthread_cond_t *)cond,
+                                  (pthread_mutex_t *) entered_mutex);
+      timed_out = FALSE;
     }
+  else
+    {
+      end_time.tv_sec = abs_time->tv_sec;
+      end_time.tv_nsec = abs_time->tv_usec * (G_NSEC_PER_SEC / G_USEC_PER_SEC);
 
-  end_time.tv_sec = abs_time->tv_sec;
-  end_time.tv_nsec = abs_time->tv_usec * (G_NSEC_PER_SEC / G_USEC_PER_SEC);
-
-  g_return_val_if_fail (end_time.tv_nsec < G_NSEC_PER_SEC, TRUE);
-
-  result = pthread_cond_timedwait ((pthread_cond_t *) cond,
-                                  (pthread_mutex_t *) entered_mutex,
-                                  &end_time);
+      g_return_val_if_fail (end_time.tv_nsec < G_NSEC_PER_SEC, TRUE);
 
+      result = pthread_cond_timedwait ((pthread_cond_t *) cond,
+                                       (pthread_mutex_t *) entered_mutex,
+                                       &end_time);
 #ifdef G_THREADS_IMPL_POSIX
-  timed_out = (result == ETIMEDOUT);
+      timed_out = (result == ETIMEDOUT);
 #else /* G_THREADS_IMPL_DCE */
-  timed_out = (result == -1) && (errno == EAGAIN);
+      timed_out = (result == -1) && (errno == EAGAIN);
 #endif
+    }
 
   if (!timed_out)
     posix_check_err (posix_error (result), "pthread_cond_timedwait");
+
   return !timed_out;
 }
 
@@ -277,7 +280,7 @@ g_private_get_posix_impl (GPrivate * private_key)
 #else /* G_THREADS_IMPL_DCE */
   {
     void* data;
-    posix_check_cmd (pthread_getspecific (*(pthread_key_t *) private_key, 
+    posix_check_cmd (pthread_getspecific (*(pthread_key_t *) private_key,
                                          &data));
     return data;
   }
@@ -285,8 +288,8 @@ g_private_get_posix_impl (GPrivate * private_key)
 }
 
 static void
-g_thread_create_posix_impl (GThreadFunc thread_func, 
-                           gpointer arg, 
+g_thread_create_posix_impl (GThreadFunc thread_func,
+                           gpointer arg,
                            gulong stack_size,
                            gboolean joinable,
                            gboolean bound,
@@ -302,7 +305,7 @@ g_thread_create_posix_impl (GThreadFunc thread_func,
   g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT);
 
   posix_check_cmd (pthread_attr_init (&attr));
-  
+
 #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
   if (stack_size)
     {
@@ -324,7 +327,7 @@ g_thread_create_posix_impl (GThreadFunc thread_func,
   posix_check_cmd (pthread_attr_setdetachstate (&attr,
           joinable ? PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED));
 #endif /* G_THREADS_IMPL_POSIX */
-  
+
 #ifdef HAVE_PRIORITIES
 # ifdef G_THREADS_IMPL_POSIX
   {
@@ -334,11 +337,11 @@ g_thread_create_posix_impl (GThreadFunc thread_func,
     posix_check_cmd_prio (pthread_attr_setschedparam (&attr, &sched));
   }
 # else /* G_THREADS_IMPL_DCE */
-  posix_check_cmd_prio 
+  posix_check_cmd_prio
     (pthread_attr_setprio (&attr, g_thread_priority_map [priority]));
 # endif /* G_THREADS_IMPL_DCE */
 #endif /* HAVE_PRIORITIES */
-  ret = posix_error (pthread_create (thread, &attr, 
+  ret = posix_error (pthread_create (thread, &attr,
                                     (void* (*)(void*))thread_func, arg));
 
   posix_check_cmd (pthread_attr_destroy (&attr));
@@ -358,7 +361,7 @@ g_thread_create_posix_impl (GThreadFunc thread_func,
 #endif /* G_THREADS_IMPL_DCE */
 }
 
-static void 
+static void
 g_thread_yield_posix_impl (void)
 {
   POSIX_YIELD_FUNC;
@@ -366,13 +369,13 @@ g_thread_yield_posix_impl (void)
 
 static void
 g_thread_join_posix_impl (gpointer thread)
-{     
+{
   gpointer ignore;
   posix_check_cmd (pthread_join (*(pthread_t*)thread, &ignore));
 }
 
-static void 
-g_thread_exit_posix_impl (void) 
+static void
+g_thread_exit_posix_impl (void)
 {
   pthread_exit (NULL);
 }
@@ -387,14 +390,14 @@ g_thread_set_priority_posix_impl (gpointer thread, GThreadPriority priority)
   {
     struct sched_param sched;
     int policy;
-    posix_check_cmd (pthread_getschedparam (*(pthread_t*)thread, &policy, 
+    posix_check_cmd (pthread_getschedparam (*(pthread_t*)thread, &policy,
                                            &sched));
     sched.sched_priority = g_thread_priority_map [priority];
-    posix_check_cmd_prio (pthread_setschedparam (*(pthread_t*)thread, policy, 
+    posix_check_cmd_prio (pthread_setschedparam (*(pthread_t*)thread, policy,
                                                 &sched));
   }
 # else /* G_THREADS_IMPL_DCE */
-  posix_check_cmd_prio (pthread_setprio (*(pthread_t*)thread, 
+  posix_check_cmd_prio (pthread_setprio (*(pthread_t*)thread,
                                         g_thread_priority_map [priority]));
 # endif
 #endif /* HAVE_PRIORITIES */
index dda2693..7b85b19 100644 (file)
  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
  * file for a list of people on the GLib Team.  See the ChangeLog
  * files for a list of changes.  These files are distributed with
- * GLib at ftp://ftp.gtk.org/pub/gtk/. 
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
  */
 
-/* 
+/*
  * MT safe
  */
 
@@ -76,6 +76,9 @@ static GDestroyNotify g_private_destructors[G_PRIVATE_MAX];
 
 static guint g_private_next = 0;
 
+/* A "forward" declaration of this structure */
+static GThreadFunctions g_thread_functions_for_glib_use_default;
+
 typedef struct _GThreadData GThreadData;
 struct _GThreadData
 {
@@ -85,7 +88,7 @@ struct _GThreadData
   gboolean joinable;
 };
 
-struct _GCond 
+struct _GCond
 {
   GPtrArray *array;
   CRITICAL_SECTION lock;
@@ -165,7 +168,7 @@ static gboolean
 g_mutex_trylock_win32_impl (GMutex * mutex)
 {
   DWORD result;
-  win32_check_for_error (WAIT_FAILED != 
+  win32_check_for_error (WAIT_FAILED !=
                         (result = WaitForSingleObject (*(HANDLE *)mutex, 0)));
   return result != WAIT_TIMEOUT;
 }
@@ -236,12 +239,12 @@ g_cond_wait_internal (GCond *cond,
   g_ptr_array_add (cond->array, event);
   LeaveCriticalSection (&cond->lock);
 
-  g_mutex_unlock (entered_mutex);
+  g_thread_functions_for_glib_use_default.mutex_unlock (entered_mutex);
 
   win32_check_for_error (WAIT_FAILED !=
                         (retval = WaitForSingleObject (event, milliseconds)));
 
-  g_mutex_lock (entered_mutex);
+  g_thread_functions_for_glib_use_default.mutex_lock (entered_mutex);
 
   if (retval == WAIT_TIMEOUT)
     {
@@ -252,7 +255,7 @@ g_cond_wait_internal (GCond *cond,
        * wait for the signal, this time with no timeout, to reset
        * it. retval is set again to honour the late arrival of the
        * signal */
-      win32_check_for_error (WAIT_FAILED != 
+      win32_check_for_error (WAIT_FAILED !=
                             (retval = WaitForSingleObject (event, 0)));
 
       LeaveCriticalSection (&cond->lock);
@@ -270,7 +273,7 @@ g_cond_wait_internal (GCond *cond,
   return retval != WAIT_TIMEOUT;
 }
 
-static void     
+static void
 g_cond_wait_win32_impl (GCond *cond,
                        GMutex *entered_mutex)
 {
@@ -281,7 +284,7 @@ g_cond_wait_win32_impl (GCond *cond,
 }
 
 static gboolean
-g_cond_timed_wait_win32_impl (GCond *cond, 
+g_cond_timed_wait_win32_impl (GCond *cond,
                              GMutex *entered_mutex,
                              GTimeVal *abs_time)
 {
@@ -302,9 +305,9 @@ g_cond_timed_wait_win32_impl (GCond *cond,
        to_wait = 0;
       else
        to_wait = (abs_time->tv_sec - current_time.tv_sec) * 1000 +
-         (abs_time->tv_usec - current_time.tv_usec) / 1000;      
+         (abs_time->tv_usec - current_time.tv_usec) / 1000;
     }
-  
+
   return g_cond_wait_internal (cond, entered_mutex, to_wait);
 }
 
@@ -381,13 +384,13 @@ g_thread_set_priority_win32_impl (gpointer thread, GThreadPriority priority)
   g_return_if_fail (priority >= G_THREAD_PRIORITY_LOW);
   g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT);
 
-  win32_check_for_error (SetThreadPriority (target->thread,  
+  win32_check_for_error (SetThreadPriority (target->thread,
                                            g_thread_priority_map [priority]));
 }
 
 static void
 g_thread_self_win32_impl (gpointer thread)
-{  
+{
   GThreadData *self = TlsGetValue (g_thread_self_tls);
 
   if (!self)
@@ -396,19 +399,19 @@ g_thread_self_win32_impl (gpointer thread)
       HANDLE handle = GetCurrentThread ();
       HANDLE process = GetCurrentProcess ();
       self = g_new (GThreadData, 1);
-      win32_check_for_error (DuplicateHandle (process, handle, process, 
-                                             &self->thread, 0, FALSE, 
+      win32_check_for_error (DuplicateHandle (process, handle, process,
+                                             &self->thread, 0, FALSE,
                                              DUPLICATE_SAME_ACCESS));
       win32_check_for_error (TlsSetValue (g_thread_self_tls, self));
       self->func = NULL;
-      self->data = NULL;      
+      self->data = NULL;
       self->joinable = FALSE;
     }
 
   *(GThreadData **)thread = self;
 }
 
-static void 
+static void
 g_thread_exit_win32_impl (void)
 {
   GThreadData *self = TlsGetValue (g_thread_self_tls);
@@ -430,12 +433,12 @@ g_thread_exit_win32_impl (void)
          {
            GDestroyNotify destructor = g_private_destructors[i];
            GDestroyNotify data = array[i];
-           
+
            if (data)
              some_data_non_null = TRUE;
 
            array[i] = NULL;
-           
+
            if (destructor && data)
              destructor (data);
          }
@@ -445,7 +448,7 @@ g_thread_exit_win32_impl (void)
 
       win32_check_for_error (TlsSetValue (g_private_tls, NULL));
     }
-  
+
   if (self)
     {
       if (!self->joinable)
@@ -471,7 +474,7 @@ g_thread_proxy (gpointer data)
   GThreadData *self = (GThreadData*) data;
 
   win32_check_for_error (TlsSetValue (g_thread_self_tls, self));
-  
+
   self->func (self->data);
 
   g_thread_exit_win32_impl ();
@@ -482,35 +485,35 @@ g_thread_proxy (gpointer data)
 }
 
 static void
-g_thread_create_win32_impl (GThreadFunc func, 
-                           gpointer data, 
+g_thread_create_win32_impl (GThreadFunc func,
+                           gpointer data,
                            gulong stack_size,
                            gboolean joinable,
                            gboolean bound,
                            GThreadPriority priority,
                            gpointer thread,
                            GError **error)
-{     
+{
   guint ignore;
   GThreadData *retval;
 
   g_return_if_fail (func);
   g_return_if_fail (priority >= G_THREAD_PRIORITY_LOW);
   g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT);
-  
+
   retval = g_new(GThreadData, 1);
   retval->func = func;
   retval->data = data;
-  
+
   retval->joinable = joinable;
 
-  retval->thread = (HANDLE) _beginthreadex (NULL, stack_size, g_thread_proxy, 
+  retval->thread = (HANDLE) _beginthreadex (NULL, stack_size, g_thread_proxy,
                                            retval, 0, &ignore);
 
   if (retval->thread == NULL)
     {
       gchar *win_error = g_win32_error_message (GetLastError ());
-      g_set_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN, 
+      g_set_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN,
                    "Error creating thread: %s", win_error);
       g_free (retval);
       g_free (win_error);
@@ -522,7 +525,7 @@ g_thread_create_win32_impl (GThreadFunc func,
   g_thread_set_priority_win32_impl (thread, priority);
 }
 
-static void 
+static void
 g_thread_yield_win32_impl (void)
 {
   Sleep(0);
@@ -535,7 +538,7 @@ g_thread_join_win32_impl (gpointer thread)
 
   g_return_if_fail (target->joinable);
 
-  win32_check_for_error (WAIT_FAILED != 
+  win32_check_for_error (WAIT_FAILED !=
                         WaitForSingleObject (target->thread, INFINITE));
 
   win32_check_for_error (CloseHandle (target->thread));
@@ -578,12 +581,12 @@ g_thread_impl_init ()
     return;
 
   beenhere = TRUE;
-  
-  win32_check_for_error (TLS_OUT_OF_INDEXES != 
+
+  win32_check_for_error (TLS_OUT_OF_INDEXES !=
                         (g_thread_self_tls = TlsAlloc ()));
-  win32_check_for_error (TLS_OUT_OF_INDEXES != 
+  win32_check_for_error (TLS_OUT_OF_INDEXES !=
                         (g_private_tls = TlsAlloc ()));
-  win32_check_for_error (TLS_OUT_OF_INDEXES != 
+  win32_check_for_error (TLS_OUT_OF_INDEXES !=
                         (g_cond_event_tls = TlsAlloc ()));
   InitializeCriticalSection (&g_thread_global_spinlock);
 
@@ -597,10 +600,10 @@ g_thread_impl_init ()
     {
       try_enter_critical_section = (GTryEnterCriticalSectionFunc)
        GetProcAddress(kernel32, "TryEnterCriticalSection");
-      
+
       /* Even if TryEnterCriticalSection is found, it is not
        * necessarily working..., we have to check it */
-      if (try_enter_critical_section && 
+      if (try_enter_critical_section &&
          try_enter_critical_section (&g_thread_global_spinlock))
        {
          LeaveCriticalSection (&g_thread_global_spinlock);