mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-11-04 10:08:56 +01:00 
			
		
		
		
	implemented g_once_init_enter(), g_once_init_enter_impl() and
Tue Jul 10 12:24:35 2007 Tim Janik <timj@imendio.com> * glib/gthread.[hc]: implemented g_once_init_enter(), g_once_init_enter_impl() and g_once_init_leave(), based on a patch by Antoine Tremblay, fixes #65041. adapted exported inline function mechanism from gutils.[hc] for inlining g_once_init_enter_impl() in gthread.[hc]. svn path=/trunk/; revision=5616
This commit is contained in:
		@@ -1,3 +1,11 @@
 | 
			
		||||
Tue Jul 10 12:24:35 2007  Tim Janik  <timj@imendio.com>
 | 
			
		||||
 | 
			
		||||
	* glib/gthread.[hc]: implemented g_once_init_enter(),
 | 
			
		||||
	g_once_init_enter_impl() and g_once_init_leave(), based on a patch by
 | 
			
		||||
	Antoine Tremblay, fixes #65041.
 | 
			
		||||
	adapted exported inline function mechanism from gutils.[hc] for inlining
 | 
			
		||||
	g_once_init_enter_impl() in gthread.[hc].
 | 
			
		||||
 | 
			
		||||
2007-07-09  Matthias Clasen  <mclasen@redhat.com>
 | 
			
		||||
 | 
			
		||||
	* NEWS: Updates
 | 
			
		||||
 
 | 
			
		||||
@@ -1172,7 +1172,10 @@ g_str_hash
 | 
			
		||||
#if IN_HEADER(__G_THREAD_H__)
 | 
			
		||||
#if IN_FILE(__G_THREAD_C__)
 | 
			
		||||
g_once_impl
 | 
			
		||||
g_once_init_enter_impl
 | 
			
		||||
g_once_init_leave
 | 
			
		||||
#ifdef INCLUDE_INTERNAL_SYMBOLS
 | 
			
		||||
g_once_init_enter
 | 
			
		||||
g_thread_init_glib
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef INCLUDE_VARIABLES
 | 
			
		||||
 
 | 
			
		||||
@@ -32,6 +32,10 @@
 | 
			
		||||
 * MT safe
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* implement gthread.h's inline functions */
 | 
			
		||||
#define G_IMPLEMENT_INLINES 1
 | 
			
		||||
#define __G_THREAD_C__
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include "glib.h"
 | 
			
		||||
@@ -121,6 +125,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);
 | 
			
		||||
 | 
			
		||||
@@ -194,6 +199,41 @@ g_once_impl (GOnce       *once,
 | 
			
		||||
  return once->retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
g_once_init_enter_impl (volatile gsize *value_location)
 | 
			
		||||
{
 | 
			
		||||
  gboolean need_init;
 | 
			
		||||
  g_mutex_lock (g_once_mutex);
 | 
			
		||||
  if (!g_once_init_list || !g_slist_find (g_once_init_list, (void*) value_location))
 | 
			
		||||
    {
 | 
			
		||||
      g_once_init_list = g_slist_prepend (g_once_init_list, (void*) value_location);
 | 
			
		||||
      need_init = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      while (g_slist_find (g_once_init_list, (void*) value_location))
 | 
			
		||||
        g_cond_wait (g_once_cond, g_once_mutex);
 | 
			
		||||
      need_init = FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  g_mutex_unlock (g_once_mutex);
 | 
			
		||||
  return need_init;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
g_once_init_leave (volatile gsize *value_location,
 | 
			
		||||
                   gsize           initialization_value)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (g_atomic_pointer_get (value_location) == 0);
 | 
			
		||||
  g_return_if_fail (initialization_value != 0);
 | 
			
		||||
  g_return_if_fail (g_once_init_list != NULL);
 | 
			
		||||
 | 
			
		||||
  g_atomic_pointer_set (value_location, initialization_value);
 | 
			
		||||
  g_mutex_lock (g_once_mutex);
 | 
			
		||||
  g_once_init_list = g_slist_remove (g_once_init_list, (void*) value_location);
 | 
			
		||||
  g_cond_broadcast (g_once_cond);
 | 
			
		||||
  g_mutex_unlock (g_once_mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
g_static_mutex_init (GStaticMutex *mutex)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,7 @@
 | 
			
		||||
 | 
			
		||||
#include <glib/gerror.h>
 | 
			
		||||
#include <glib/gtypes.h>
 | 
			
		||||
#include <glib/gutils.h>        /* for G_INLINE_FUNC */
 | 
			
		||||
#include <glib/gatomic.h>       /* for g_atomic_pointer_get */
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
@@ -322,6 +323,22 @@ gpointer g_once_impl (GOnce *once, GThreadFunc func, gpointer arg);
 | 
			
		||||
   g_once_impl ((once), (func), (arg)))
 | 
			
		||||
#endif /* G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */
 | 
			
		||||
 | 
			
		||||
/* initialize-once guards, keyed by value_location */
 | 
			
		||||
G_INLINE_FUNC gboolean  g_once_init_enter       (volatile gsize *value_location);
 | 
			
		||||
gboolean                g_once_init_enter_impl  (volatile gsize *value_location);
 | 
			
		||||
void                    g_once_init_leave       (volatile gsize *value_location,
 | 
			
		||||
                                                 gsize           initialization_value);
 | 
			
		||||
#if defined (G_CAN_INLINE) || defined (__G_THREAD_C__)
 | 
			
		||||
G_INLINE_FUNC gboolean
 | 
			
		||||
g_once_init_enter (volatile gsize *value_location)
 | 
			
		||||
{
 | 
			
		||||
  if G_LIKELY (g_atomic_pointer_get (value_location) !=0)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
  else
 | 
			
		||||
    return g_once_init_enter_impl (value_location);
 | 
			
		||||
}
 | 
			
		||||
#endif /* G_CAN_INLINE || __G_THREAD_C__ */
 | 
			
		||||
 | 
			
		||||
/* 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)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user