--- glib-2.12.4-org/glib/gthread.h	2006-05-10 20:18:46.000000000 -0400
+++ glib-2.12.4/glib/gthread.h	2007-04-14 13:33:43.000000000 -0400
@@ -319,7 +319,21 @@ gpointer g_once_impl (GOnce *once, GThre
    (once)->retval : \
    g_once_impl ((once), (func), (arg)))
 #endif /* G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */
-    
+
+gboolean  g_once_init_enter_locked (volatile gsize *value_location);
+void  g_once_init_leave (volatile gsize *value_location,  gsize value);
+
+static inline gboolean  
+g_once_init_enter (volatile gsize *value_location) {
+ 
+  if (g_atomic_pointer_get (value_location) !=0)
+  {
+    return FALSE;
+  }
+  
+  return g_once_init_enter_locked(value_location);
+}
+
 /* these are some convenience macros that expand to nothing if GLib
  * was configured with --disable-threads. for using StaticMutexes,
  * you define them with G_LOCK_DEFINE_STATIC (name) or G_LOCK_DEFINE (name)
--- glib-2.12.4-org/glib/gthread.c	2006-05-22 21:33:16.000000000 -0400
+++ glib-2.12.4/glib/gthread.c	2007-04-14 13:49:15.000000000 -0400
@@ -109,6 +109,7 @@ static GCond    *g_once_cond = NULL;
 static GPrivate *g_thread_specific_private = NULL;
 static GRealThread *g_thread_all_threads = NULL;
 static GSList   *g_thread_free_indeces = NULL;
+static GSList  *g_once_init_list = NULL;
 
 G_LOCK_DEFINE_STATIC (g_thread);
 
@@ -182,6 +183,47 @@ g_once_impl (GOnce       *once,
   return once->retval;
 }
 
+gboolean
+g_once_init_enter_locked (volatile gsize *value_location)
+{
+  if (g_atomic_pointer_get (value_location) !=0)
+    return FALSE;
+    
+  g_mutex_lock (g_once_mutex);
+  if (!g_once_init_list || !g_slist_find (g_once_init_list, (gpointer) value_location))
+    {
+      g_once_init_list = g_slist_prepend (g_once_init_list, (gpointer) value_location);
+      g_mutex_unlock (g_once_mutex);
+      return  TRUE;
+    }
+  else
+    {
+      while(g_once_init_list && g_slist_find (g_once_init_list, (gpointer) value_location))
+        g_cond_wait (g_once_cond, g_once_mutex);
+      
+      g_mutex_unlock (g_once_mutex);
+    }
+  
+  return FALSE;  
+}
+
+
+void  
+g_once_init_leave (volatile gsize *value_location,  gsize value)
+{
+  g_return_if_fail (g_atomic_pointer_get(value_location) == 0);
+  g_return_if_fail (value != 0);
+  g_return_if_fail (g_once_init_list != NULL);
+  
+  g_atomic_pointer_set (value_location, value);
+  
+  g_mutex_lock (g_once_mutex);
+  g_once_init_list = g_slist_remove (g_once_init_list, (gpointer) value_location);
+  g_cond_broadcast (g_once_cond);
+  g_mutex_unlock (g_once_mutex);
+  
+}
+
 void
 g_static_mutex_init (GStaticMutex *mutex)
 {
