mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-11-03 17:48:56 +01:00 
			
		
		
		
	Added functions g_static_rec_mutex_init, g_static_rec_mutex_free,
2001-02-13 Sebastian Wilhelmi <wilhelmi@ira.uka.de> * gthread.c, gthread.h: Added functions g_static_rec_mutex_init, g_static_rec_mutex_free, g_static_private_init, g_static_private_free, g_static_rw_lock_init to allow the usage of all those types dynamically. (g_static_rw_lock_free already existed). Aditionally freed static_private indeces are reused now. Untill now the array would just grow if you would use more and more static_private. That required adding a slist of all running threads, which could potentially be of good use later. It is not exported however. Renamed a LOCK and small indentation fixes. * tests/thread-test.c: Test the new static_private index freing and reusing feature.
This commit is contained in:
		
				
					committed by
					
						
						Sebastian Wilhelmi
					
				
			
			
				
	
			
			
			
						parent
						
							cc0f6f0232
						
					
				
				
					commit
					41e2001d85
				
			
							
								
								
									
										16
									
								
								ChangeLog
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								ChangeLog
									
									
									
									
									
								
							@@ -1,3 +1,19 @@
 | 
			
		||||
2001-02-13  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
 | 
			
		||||
 | 
			
		||||
	* gthread.c, gthread.h: Added functions g_static_rec_mutex_init,
 | 
			
		||||
	g_static_rec_mutex_free, g_static_private_init,
 | 
			
		||||
	g_static_private_free, g_static_rw_lock_init to allow the usage of
 | 
			
		||||
	all those types dynamically. (g_static_rw_lock_free already
 | 
			
		||||
	existed). Aditionally freed static_private indeces are reused
 | 
			
		||||
	now. Untill now the array would just grow if you would use more
 | 
			
		||||
	and more static_private. That required adding a slist of all
 | 
			
		||||
	running threads, which could potentially be of good use later. It
 | 
			
		||||
	is not exported however. Renamed a LOCK and small indentation
 | 
			
		||||
	fixes.
 | 
			
		||||
 | 
			
		||||
	* tests/thread-test.c: Test the new static_private index freing
 | 
			
		||||
	and reusing feature.
 | 
			
		||||
	
 | 
			
		||||
Mon Feb 12 15:01:09 2001  Owen Taylor  <otaylor@redhat.com>
 | 
			
		||||
 | 
			
		||||
	* configure.in (gtk_doc_min_version): Add check for gtk-doc version.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,19 @@
 | 
			
		||||
2001-02-13  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
 | 
			
		||||
 | 
			
		||||
	* gthread.c, gthread.h: Added functions g_static_rec_mutex_init,
 | 
			
		||||
	g_static_rec_mutex_free, g_static_private_init,
 | 
			
		||||
	g_static_private_free, g_static_rw_lock_init to allow the usage of
 | 
			
		||||
	all those types dynamically. (g_static_rw_lock_free already
 | 
			
		||||
	existed). Aditionally freed static_private indeces are reused
 | 
			
		||||
	now. Untill now the array would just grow if you would use more
 | 
			
		||||
	and more static_private. That required adding a slist of all
 | 
			
		||||
	running threads, which could potentially be of good use later. It
 | 
			
		||||
	is not exported however. Renamed a LOCK and small indentation
 | 
			
		||||
	fixes.
 | 
			
		||||
 | 
			
		||||
	* tests/thread-test.c: Test the new static_private index freing
 | 
			
		||||
	and reusing feature.
 | 
			
		||||
	
 | 
			
		||||
Mon Feb 12 15:01:09 2001  Owen Taylor  <otaylor@redhat.com>
 | 
			
		||||
 | 
			
		||||
	* configure.in (gtk_doc_min_version): Add check for gtk-doc version.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,19 @@
 | 
			
		||||
2001-02-13  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
 | 
			
		||||
 | 
			
		||||
	* gthread.c, gthread.h: Added functions g_static_rec_mutex_init,
 | 
			
		||||
	g_static_rec_mutex_free, g_static_private_init,
 | 
			
		||||
	g_static_private_free, g_static_rw_lock_init to allow the usage of
 | 
			
		||||
	all those types dynamically. (g_static_rw_lock_free already
 | 
			
		||||
	existed). Aditionally freed static_private indeces are reused
 | 
			
		||||
	now. Untill now the array would just grow if you would use more
 | 
			
		||||
	and more static_private. That required adding a slist of all
 | 
			
		||||
	running threads, which could potentially be of good use later. It
 | 
			
		||||
	is not exported however. Renamed a LOCK and small indentation
 | 
			
		||||
	fixes.
 | 
			
		||||
 | 
			
		||||
	* tests/thread-test.c: Test the new static_private index freing
 | 
			
		||||
	and reusing feature.
 | 
			
		||||
	
 | 
			
		||||
Mon Feb 12 15:01:09 2001  Owen Taylor  <otaylor@redhat.com>
 | 
			
		||||
 | 
			
		||||
	* configure.in (gtk_doc_min_version): Add check for gtk-doc version.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,19 @@
 | 
			
		||||
2001-02-13  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
 | 
			
		||||
 | 
			
		||||
	* gthread.c, gthread.h: Added functions g_static_rec_mutex_init,
 | 
			
		||||
	g_static_rec_mutex_free, g_static_private_init,
 | 
			
		||||
	g_static_private_free, g_static_rw_lock_init to allow the usage of
 | 
			
		||||
	all those types dynamically. (g_static_rw_lock_free already
 | 
			
		||||
	existed). Aditionally freed static_private indeces are reused
 | 
			
		||||
	now. Untill now the array would just grow if you would use more
 | 
			
		||||
	and more static_private. That required adding a slist of all
 | 
			
		||||
	running threads, which could potentially be of good use later. It
 | 
			
		||||
	is not exported however. Renamed a LOCK and small indentation
 | 
			
		||||
	fixes.
 | 
			
		||||
 | 
			
		||||
	* tests/thread-test.c: Test the new static_private index freing
 | 
			
		||||
	and reusing feature.
 | 
			
		||||
	
 | 
			
		||||
Mon Feb 12 15:01:09 2001  Owen Taylor  <otaylor@redhat.com>
 | 
			
		||||
 | 
			
		||||
	* configure.in (gtk_doc_min_version): Add check for gtk-doc version.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,19 @@
 | 
			
		||||
2001-02-13  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
 | 
			
		||||
 | 
			
		||||
	* gthread.c, gthread.h: Added functions g_static_rec_mutex_init,
 | 
			
		||||
	g_static_rec_mutex_free, g_static_private_init,
 | 
			
		||||
	g_static_private_free, g_static_rw_lock_init to allow the usage of
 | 
			
		||||
	all those types dynamically. (g_static_rw_lock_free already
 | 
			
		||||
	existed). Aditionally freed static_private indeces are reused
 | 
			
		||||
	now. Untill now the array would just grow if you would use more
 | 
			
		||||
	and more static_private. That required adding a slist of all
 | 
			
		||||
	running threads, which could potentially be of good use later. It
 | 
			
		||||
	is not exported however. Renamed a LOCK and small indentation
 | 
			
		||||
	fixes.
 | 
			
		||||
 | 
			
		||||
	* tests/thread-test.c: Test the new static_private index freing
 | 
			
		||||
	and reusing feature.
 | 
			
		||||
	
 | 
			
		||||
Mon Feb 12 15:01:09 2001  Owen Taylor  <otaylor@redhat.com>
 | 
			
		||||
 | 
			
		||||
	* configure.in (gtk_doc_min_version): Add check for gtk-doc version.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,19 @@
 | 
			
		||||
2001-02-13  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
 | 
			
		||||
 | 
			
		||||
	* gthread.c, gthread.h: Added functions g_static_rec_mutex_init,
 | 
			
		||||
	g_static_rec_mutex_free, g_static_private_init,
 | 
			
		||||
	g_static_private_free, g_static_rw_lock_init to allow the usage of
 | 
			
		||||
	all those types dynamically. (g_static_rw_lock_free already
 | 
			
		||||
	existed). Aditionally freed static_private indeces are reused
 | 
			
		||||
	now. Untill now the array would just grow if you would use more
 | 
			
		||||
	and more static_private. That required adding a slist of all
 | 
			
		||||
	running threads, which could potentially be of good use later. It
 | 
			
		||||
	is not exported however. Renamed a LOCK and small indentation
 | 
			
		||||
	fixes.
 | 
			
		||||
 | 
			
		||||
	* tests/thread-test.c: Test the new static_private index freing
 | 
			
		||||
	and reusing feature.
 | 
			
		||||
	
 | 
			
		||||
Mon Feb 12 15:01:09 2001  Owen Taylor  <otaylor@redhat.com>
 | 
			
		||||
 | 
			
		||||
	* configure.in (gtk_doc_min_version): Add check for gtk-doc version.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,19 @@
 | 
			
		||||
2001-02-13  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
 | 
			
		||||
 | 
			
		||||
	* gthread.c, gthread.h: Added functions g_static_rec_mutex_init,
 | 
			
		||||
	g_static_rec_mutex_free, g_static_private_init,
 | 
			
		||||
	g_static_private_free, g_static_rw_lock_init to allow the usage of
 | 
			
		||||
	all those types dynamically. (g_static_rw_lock_free already
 | 
			
		||||
	existed). Aditionally freed static_private indeces are reused
 | 
			
		||||
	now. Untill now the array would just grow if you would use more
 | 
			
		||||
	and more static_private. That required adding a slist of all
 | 
			
		||||
	running threads, which could potentially be of good use later. It
 | 
			
		||||
	is not exported however. Renamed a LOCK and small indentation
 | 
			
		||||
	fixes.
 | 
			
		||||
 | 
			
		||||
	* tests/thread-test.c: Test the new static_private index freing
 | 
			
		||||
	and reusing feature.
 | 
			
		||||
	
 | 
			
		||||
Mon Feb 12 15:01:09 2001  Owen Taylor  <otaylor@redhat.com>
 | 
			
		||||
 | 
			
		||||
	* configure.in (gtk_doc_min_version): Add check for gtk-doc version.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,19 @@
 | 
			
		||||
2001-02-13  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
 | 
			
		||||
 | 
			
		||||
	* gthread.c, gthread.h: Added functions g_static_rec_mutex_init,
 | 
			
		||||
	g_static_rec_mutex_free, g_static_private_init,
 | 
			
		||||
	g_static_private_free, g_static_rw_lock_init to allow the usage of
 | 
			
		||||
	all those types dynamically. (g_static_rw_lock_free already
 | 
			
		||||
	existed). Aditionally freed static_private indeces are reused
 | 
			
		||||
	now. Untill now the array would just grow if you would use more
 | 
			
		||||
	and more static_private. That required adding a slist of all
 | 
			
		||||
	running threads, which could potentially be of good use later. It
 | 
			
		||||
	is not exported however. Renamed a LOCK and small indentation
 | 
			
		||||
	fixes.
 | 
			
		||||
 | 
			
		||||
	* tests/thread-test.c: Test the new static_private index freing
 | 
			
		||||
	and reusing feature.
 | 
			
		||||
	
 | 
			
		||||
Mon Feb 12 15:01:09 2001  Owen Taylor  <otaylor@redhat.com>
 | 
			
		||||
 | 
			
		||||
	* configure.in (gtk_doc_min_version): Add check for gtk-doc version.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										178
									
								
								glib/gthread.c
									
									
									
									
									
								
							
							
						
						
									
										178
									
								
								glib/gthread.c
									
									
									
									
									
								
							@@ -52,7 +52,7 @@
 | 
			
		||||
#endif /* GLIB_SIZEOF_SYSTEM_THREAD == SIZEOF_VOID_P */
 | 
			
		||||
 | 
			
		||||
GQuark 
 | 
			
		||||
g_thread_error_quark()
 | 
			
		||||
g_thread_error_quark (void)
 | 
			
		||||
{
 | 
			
		||||
  static GQuark quark;
 | 
			
		||||
  if (!quark)
 | 
			
		||||
@@ -117,8 +117,11 @@ GThreadFunctions g_thread_functions_for_glib_use = {
 | 
			
		||||
/* Local data */
 | 
			
		||||
 | 
			
		||||
static GMutex   *g_mutex_protect_static_mutex_allocation = NULL;
 | 
			
		||||
static GMutex   *g_thread_specific_mutex = NULL;
 | 
			
		||||
static GPrivate *g_thread_specific_private = NULL;
 | 
			
		||||
static GSList   *g_thread_all_threads = NULL;
 | 
			
		||||
static GSList   *g_thread_free_indeces = NULL;
 | 
			
		||||
 | 
			
		||||
G_LOCK_DEFINE_STATIC (g_thread);
 | 
			
		||||
 | 
			
		||||
/* This must be called only once, before any threads are created.
 | 
			
		||||
 * It will only be called from g_thread_init() in -lgthread.
 | 
			
		||||
@@ -137,8 +140,17 @@ g_mutex_init (void)
 | 
			
		||||
  G_THREAD_UF (private_set, (g_thread_specific_private, main_thread));
 | 
			
		||||
  G_THREAD_UF (thread_self, (&main_thread->system_thread));
 | 
			
		||||
 | 
			
		||||
  g_mutex_protect_static_mutex_allocation = g_mutex_new();
 | 
			
		||||
  g_thread_specific_mutex = g_mutex_new();
 | 
			
		||||
  g_mutex_protect_static_mutex_allocation = g_mutex_new ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void 
 | 
			
		||||
g_static_mutex_init (GStaticMutex *mutex)
 | 
			
		||||
{
 | 
			
		||||
  static GStaticMutex init_mutex = G_STATIC_MUTEX_INIT;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (mutex);
 | 
			
		||||
 | 
			
		||||
  memcpy (mutex, &init_mutex, sizeof (GStaticMutex));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GMutex *
 | 
			
		||||
@@ -152,23 +164,13 @@ g_static_mutex_get_mutex_impl (GMutex** mutex)
 | 
			
		||||
  g_mutex_lock (g_mutex_protect_static_mutex_allocation);
 | 
			
		||||
 | 
			
		||||
  if (!(*mutex)) 
 | 
			
		||||
    *mutex = g_mutex_new(); 
 | 
			
		||||
    *mutex = g_mutex_new (); 
 | 
			
		||||
 | 
			
		||||
  g_mutex_unlock (g_mutex_protect_static_mutex_allocation);
 | 
			
		||||
  
 | 
			
		||||
  return *mutex;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void 
 | 
			
		||||
g_static_mutex_init (GStaticMutex *mutex)
 | 
			
		||||
{
 | 
			
		||||
  static GStaticMutex init_mutex = G_STATIC_MUTEX_INIT;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (mutex);
 | 
			
		||||
 | 
			
		||||
  memcpy (mutex, &init_mutex, sizeof (GStaticMutex));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
g_static_mutex_free (GStaticMutex* mutex)
 | 
			
		||||
{
 | 
			
		||||
@@ -186,6 +188,16 @@ g_static_mutex_free (GStaticMutex* mutex)
 | 
			
		||||
  *runtime_mutex = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void     
 | 
			
		||||
g_static_rec_mutex_init (GStaticRecMutex *mutex)
 | 
			
		||||
{
 | 
			
		||||
  static GStaticRecMutex init_mutex = G_STATIC_REC_MUTEX_INIT;
 | 
			
		||||
  
 | 
			
		||||
  g_return_if_fail (mutex);
 | 
			
		||||
 | 
			
		||||
  memcpy (mutex, &init_mutex, sizeof (GStaticRecMutex));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
g_static_rec_mutex_lock (GStaticRecMutex* mutex)
 | 
			
		||||
{
 | 
			
		||||
@@ -284,6 +296,19 @@ g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex)
 | 
			
		||||
  return depth;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
g_static_rec_mutex_free (GStaticRecMutex *mutex)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (mutex);
 | 
			
		||||
 | 
			
		||||
  g_static_mutex_free (&mutex->mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void     
 | 
			
		||||
g_static_private_init (GStaticPrivate *private_key)
 | 
			
		||||
{
 | 
			
		||||
  private_key->index = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gpointer
 | 
			
		||||
g_static_private_get (GStaticPrivate *private_key)
 | 
			
		||||
@@ -343,12 +368,23 @@ g_static_private_set_for_thread (GStaticPrivate *private_key,
 | 
			
		||||
 | 
			
		||||
  if (!private_key->index)
 | 
			
		||||
    {
 | 
			
		||||
      g_mutex_lock (g_thread_specific_mutex);
 | 
			
		||||
      G_LOCK (g_thread);
 | 
			
		||||
 | 
			
		||||
      if (!private_key->index)
 | 
			
		||||
	private_key->index = ++next_index;
 | 
			
		||||
	{
 | 
			
		||||
	  if (g_thread_free_indeces)
 | 
			
		||||
	    {
 | 
			
		||||
	      private_key->index = 
 | 
			
		||||
		GPOINTER_TO_UINT (g_thread_free_indeces->data);
 | 
			
		||||
	      g_thread_free_indeces = 
 | 
			
		||||
		g_slist_delete_link (g_thread_free_indeces,
 | 
			
		||||
				     g_thread_free_indeces);
 | 
			
		||||
	    }
 | 
			
		||||
	  else
 | 
			
		||||
	    private_key->index = ++next_index;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      g_mutex_unlock (g_thread_specific_mutex);
 | 
			
		||||
      G_UNLOCK (g_thread);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (private_key->index > array->len)
 | 
			
		||||
@@ -372,6 +408,35 @@ g_static_private_set_for_thread (GStaticPrivate *private_key,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void     
 | 
			
		||||
g_static_private_free (GStaticPrivate *private_key)
 | 
			
		||||
{
 | 
			
		||||
  GStaticPrivate copied_key;
 | 
			
		||||
  GSList *list;
 | 
			
		||||
 | 
			
		||||
  copied_key.index = private_key->index;
 | 
			
		||||
  private_key->index = 0;
 | 
			
		||||
 | 
			
		||||
  if (!copied_key.index)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  G_LOCK (g_thread);
 | 
			
		||||
  list =  g_thread_all_threads;
 | 
			
		||||
  while (list)
 | 
			
		||||
    {
 | 
			
		||||
      GThread *thread = list->data;
 | 
			
		||||
      list = list->next;
 | 
			
		||||
      
 | 
			
		||||
      G_UNLOCK (g_thread);
 | 
			
		||||
      g_static_private_set_for_thread (&copied_key, thread, NULL, NULL);
 | 
			
		||||
      G_LOCK (g_thread);
 | 
			
		||||
    }
 | 
			
		||||
  g_thread_free_indeces = 
 | 
			
		||||
    g_slist_prepend (g_thread_free_indeces, 
 | 
			
		||||
		     GUINT_TO_POINTER (copied_key.index));
 | 
			
		||||
  G_UNLOCK (g_thread);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_thread_cleanup (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
@@ -396,6 +461,10 @@ g_thread_cleanup (gpointer data)
 | 
			
		||||
         it is, the structure is freed in g_thread_join */
 | 
			
		||||
      if (!thread->thread.joinable)
 | 
			
		||||
	{
 | 
			
		||||
	  G_LOCK (g_thread);
 | 
			
		||||
	  g_thread_all_threads = g_slist_remove (g_thread_all_threads, data);
 | 
			
		||||
	  G_UNLOCK (g_thread);
 | 
			
		||||
	  
 | 
			
		||||
	  /* Just to make sure, this isn't used any more */
 | 
			
		||||
	  g_system_thread_assign (thread->system_thread, zero_thread);
 | 
			
		||||
	  g_free (thread);
 | 
			
		||||
@@ -409,8 +478,6 @@ g_thread_fail (void)
 | 
			
		||||
  g_error ("The thread system is not yet initialized.");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
G_LOCK_DEFINE_STATIC (g_thread_create);
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
g_thread_create_proxy (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
@@ -423,8 +490,8 @@ g_thread_create_proxy (gpointer data)
 | 
			
		||||
 | 
			
		||||
  /* the lock makes sure, that thread->system_thread is written,
 | 
			
		||||
     before thread->func is called. See g_thread_create. */
 | 
			
		||||
  G_LOCK (g_thread_create);
 | 
			
		||||
  G_UNLOCK (g_thread_create);
 | 
			
		||||
  G_LOCK (g_thread);
 | 
			
		||||
  G_UNLOCK (g_thread);
 | 
			
		||||
 | 
			
		||||
  thread->func (thread->arg);
 | 
			
		||||
}
 | 
			
		||||
@@ -450,11 +517,12 @@ g_thread_create (GThreadFunc 		 thread_func,
 | 
			
		||||
  result->func = thread_func;
 | 
			
		||||
  result->arg = arg;
 | 
			
		||||
  result->private_data = NULL; 
 | 
			
		||||
  G_LOCK (g_thread_create);
 | 
			
		||||
  G_LOCK (g_thread);
 | 
			
		||||
  G_THREAD_UF (thread_create, (g_thread_create_proxy, result, 
 | 
			
		||||
			       stack_size, joinable, bound, priority,
 | 
			
		||||
			       &result->system_thread, &local_error));
 | 
			
		||||
  G_UNLOCK (g_thread_create);
 | 
			
		||||
  g_thread_all_threads = g_slist_prepend (g_thread_all_threads, result);
 | 
			
		||||
  G_UNLOCK (g_thread);
 | 
			
		||||
 | 
			
		||||
  if (local_error)
 | 
			
		||||
    {
 | 
			
		||||
@@ -478,6 +546,10 @@ g_thread_join (GThread* thread)
 | 
			
		||||
 | 
			
		||||
  G_THREAD_UF (thread_join, (&real->system_thread));
 | 
			
		||||
 | 
			
		||||
  G_LOCK (g_thread);
 | 
			
		||||
  g_thread_all_threads = g_slist_remove (g_thread_all_threads, thread);
 | 
			
		||||
  G_UNLOCK (g_thread);
 | 
			
		||||
 | 
			
		||||
  /* Just to make sure, this isn't used any more */
 | 
			
		||||
  thread->joinable = 0;
 | 
			
		||||
  g_system_thread_assign (real->system_thread, zero_thread);
 | 
			
		||||
@@ -505,7 +577,7 @@ g_thread_set_priority (GThread* thread,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GThread*
 | 
			
		||||
g_thread_self()
 | 
			
		||||
g_thread_self (void)
 | 
			
		||||
{
 | 
			
		||||
  GRealThread* thread = g_private_get (g_thread_specific_private);
 | 
			
		||||
 | 
			
		||||
@@ -526,20 +598,36 @@ g_thread_self()
 | 
			
		||||
      if (g_thread_supported ())
 | 
			
		||||
	G_THREAD_UF (thread_self, (&thread->system_thread));
 | 
			
		||||
 | 
			
		||||
      g_private_set (g_thread_specific_private, thread);
 | 
			
		||||
      g_private_set (g_thread_specific_private, thread); 
 | 
			
		||||
      
 | 
			
		||||
      G_LOCK (g_thread);
 | 
			
		||||
      g_thread_all_threads = g_slist_prepend (g_thread_all_threads, thread);
 | 
			
		||||
      G_UNLOCK (g_thread);
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return (GThread*)thread;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void inline g_static_rw_lock_wait (GCond** cond, GStaticMutex* mutex)
 | 
			
		||||
void
 | 
			
		||||
g_static_rw_lock_init (GStaticRWLock* lock)
 | 
			
		||||
{
 | 
			
		||||
  static GStaticRWLock init_lock = G_STATIC_RW_LOCK_INIT;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (lock);
 | 
			
		||||
 | 
			
		||||
  memcpy (lock, &init_lock, sizeof (GStaticRWLock));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void inline 
 | 
			
		||||
g_static_rw_lock_wait (GCond** cond, GStaticMutex* mutex)
 | 
			
		||||
{
 | 
			
		||||
  if (!*cond)
 | 
			
		||||
      *cond = g_cond_new ();
 | 
			
		||||
  g_cond_wait (*cond, g_static_mutex_get_mutex (mutex));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void inline g_static_rw_lock_signal (GStaticRWLock* lock)
 | 
			
		||||
static void inline 
 | 
			
		||||
g_static_rw_lock_signal (GStaticRWLock* lock)
 | 
			
		||||
{
 | 
			
		||||
  if (lock->want_to_write && lock->write_cond)
 | 
			
		||||
    g_cond_signal (lock->write_cond);
 | 
			
		||||
@@ -547,7 +635,8 @@ static void inline g_static_rw_lock_signal (GStaticRWLock* lock)
 | 
			
		||||
    g_cond_broadcast (lock->read_cond);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void g_static_rw_lock_reader_lock (GStaticRWLock* lock)
 | 
			
		||||
void 
 | 
			
		||||
g_static_rw_lock_reader_lock (GStaticRWLock* lock)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (lock);
 | 
			
		||||
 | 
			
		||||
@@ -561,7 +650,8 @@ void g_static_rw_lock_reader_lock (GStaticRWLock* lock)
 | 
			
		||||
  g_static_mutex_unlock (&lock->mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean g_static_rw_lock_reader_trylock (GStaticRWLock* lock)
 | 
			
		||||
gboolean 
 | 
			
		||||
g_static_rw_lock_reader_trylock (GStaticRWLock* lock)
 | 
			
		||||
{
 | 
			
		||||
  gboolean ret_val = FALSE;
 | 
			
		||||
 | 
			
		||||
@@ -580,7 +670,8 @@ gboolean g_static_rw_lock_reader_trylock (GStaticRWLock* lock)
 | 
			
		||||
  return ret_val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void g_static_rw_lock_reader_unlock  (GStaticRWLock* lock)
 | 
			
		||||
void 
 | 
			
		||||
g_static_rw_lock_reader_unlock  (GStaticRWLock* lock)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (lock);
 | 
			
		||||
 | 
			
		||||
@@ -594,7 +685,8 @@ void g_static_rw_lock_reader_unlock  (GStaticRWLock* lock)
 | 
			
		||||
  g_static_mutex_unlock (&lock->mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void g_static_rw_lock_writer_lock (GStaticRWLock* lock)
 | 
			
		||||
void 
 | 
			
		||||
g_static_rw_lock_writer_lock (GStaticRWLock* lock)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (lock);
 | 
			
		||||
 | 
			
		||||
@@ -610,7 +702,8 @@ void g_static_rw_lock_writer_lock (GStaticRWLock* lock)
 | 
			
		||||
  g_static_mutex_unlock (&lock->mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean g_static_rw_lock_writer_trylock (GStaticRWLock* lock)
 | 
			
		||||
gboolean 
 | 
			
		||||
g_static_rw_lock_writer_trylock (GStaticRWLock* lock)
 | 
			
		||||
{
 | 
			
		||||
  gboolean ret_val = FALSE;
 | 
			
		||||
 | 
			
		||||
@@ -629,7 +722,8 @@ gboolean g_static_rw_lock_writer_trylock (GStaticRWLock* lock)
 | 
			
		||||
  return ret_val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void g_static_rw_lock_writer_unlock (GStaticRWLock* lock)
 | 
			
		||||
void 
 | 
			
		||||
g_static_rw_lock_writer_unlock (GStaticRWLock* lock)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (lock);
 | 
			
		||||
  
 | 
			
		||||
@@ -642,14 +736,20 @@ void g_static_rw_lock_writer_unlock (GStaticRWLock* lock)
 | 
			
		||||
  g_static_mutex_unlock (&lock->mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void g_static_rw_lock_free (GStaticRWLock* lock)
 | 
			
		||||
void 
 | 
			
		||||
g_static_rw_lock_free (GStaticRWLock* lock)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (lock);
 | 
			
		||||
  
 | 
			
		||||
  if (lock->read_cond)
 | 
			
		||||
    g_cond_free (lock->read_cond);
 | 
			
		||||
    {
 | 
			
		||||
      g_cond_free (lock->read_cond);
 | 
			
		||||
      lock->read_cond = NULL;
 | 
			
		||||
    }
 | 
			
		||||
  if (lock->write_cond)
 | 
			
		||||
    g_cond_free (lock->write_cond);
 | 
			
		||||
  
 | 
			
		||||
    {
 | 
			
		||||
      g_cond_free (lock->write_cond);
 | 
			
		||||
      lock->write_cond = NULL;
 | 
			
		||||
    }
 | 
			
		||||
  g_static_mutex_free (&lock->mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -46,8 +46,8 @@ G_BEGIN_DECLS
 | 
			
		||||
/* GLib Thread support
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
extern GQuark g_thread_error_quark();
 | 
			
		||||
#define G_THREAD_ERROR g_thread_error_quark()
 | 
			
		||||
extern GQuark g_thread_error_quark (void);
 | 
			
		||||
#define G_THREAD_ERROR g_thread_error_quark ()
 | 
			
		||||
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
@@ -235,16 +235,18 @@ struct _GStaticPrivate
 | 
			
		||||
  guint index;
 | 
			
		||||
};
 | 
			
		||||
#define G_STATIC_PRIVATE_INIT { 0 }
 | 
			
		||||
gpointer g_static_private_get (GStaticPrivate   *private_key);
 | 
			
		||||
void     g_static_private_set (GStaticPrivate   *private_key,
 | 
			
		||||
                               gpointer          data,
 | 
			
		||||
                               GDestroyNotify    notify);
 | 
			
		||||
gpointer g_static_private_get_for_thread (GStaticPrivate *private_key,
 | 
			
		||||
                                          GThread        *thread);
 | 
			
		||||
void g_static_private_set_for_thread (GStaticPrivate *private_key,
 | 
			
		||||
                                      GThread        *thread,
 | 
			
		||||
                                      gpointer        data,
 | 
			
		||||
                                      GDestroyNotify  notify);
 | 
			
		||||
void     g_static_private_init           (GStaticPrivate   *private_key);
 | 
			
		||||
gpointer g_static_private_get            (GStaticPrivate   *private_key);
 | 
			
		||||
void     g_static_private_set            (GStaticPrivate   *private_key,
 | 
			
		||||
					  gpointer          data,
 | 
			
		||||
					  GDestroyNotify    notify);
 | 
			
		||||
gpointer g_static_private_get_for_thread (GStaticPrivate   *private_key,
 | 
			
		||||
                                          GThread          *thread);
 | 
			
		||||
void     g_static_private_set_for_thread (GStaticPrivate   *private_key,
 | 
			
		||||
					  GThread          *thread,
 | 
			
		||||
					  gpointer          data,
 | 
			
		||||
					  GDestroyNotify    notify);
 | 
			
		||||
void     g_static_private_free           (GStaticPrivate   *private_key);
 | 
			
		||||
 | 
			
		||||
typedef struct _GStaticRecMutex GStaticRecMutex;
 | 
			
		||||
struct _GStaticRecMutex
 | 
			
		||||
@@ -255,12 +257,14 @@ struct _GStaticRecMutex
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define G_STATIC_REC_MUTEX_INIT { G_STATIC_MUTEX_INIT }
 | 
			
		||||
void     g_static_rec_mutex_init        (GStaticRecMutex *mutex);
 | 
			
		||||
void     g_static_rec_mutex_lock        (GStaticRecMutex *mutex);
 | 
			
		||||
gboolean g_static_rec_mutex_trylock     (GStaticRecMutex *mutex);
 | 
			
		||||
void     g_static_rec_mutex_unlock      (GStaticRecMutex *mutex);
 | 
			
		||||
void     g_static_rec_mutex_lock_full   (GStaticRecMutex *mutex,
 | 
			
		||||
                                         guint            depth);
 | 
			
		||||
guint    g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex);
 | 
			
		||||
void     g_static_rec_mutex_free        (GStaticRecMutex *mutex);
 | 
			
		||||
 | 
			
		||||
typedef struct _GStaticRWLock GStaticRWLock;
 | 
			
		||||
struct _GStaticRWLock
 | 
			
		||||
@@ -275,13 +279,14 @@ struct _GStaticRWLock
 | 
			
		||||
 | 
			
		||||
#define G_STATIC_RW_LOCK_INIT { G_STATIC_MUTEX_INIT, NULL, NULL, 0, FALSE, FALSE }
 | 
			
		||||
 | 
			
		||||
void      g_static_rw_lock_init           (GStaticRWLock* lock);
 | 
			
		||||
void      g_static_rw_lock_reader_lock    (GStaticRWLock* lock);
 | 
			
		||||
gboolean  g_static_rw_lock_reader_trylock (GStaticRWLock* lock);
 | 
			
		||||
void      g_static_rw_lock_reader_unlock  (GStaticRWLock* lock);
 | 
			
		||||
void      g_static_rw_lock_writer_lock    (GStaticRWLock* lock);
 | 
			
		||||
gboolean  g_static_rw_lock_writer_trylock (GStaticRWLock* lock);
 | 
			
		||||
void      g_static_rw_lock_writer_unlock  (GStaticRWLock* lock);
 | 
			
		||||
void      g_static_rw_lock_free (GStaticRWLock* lock);
 | 
			
		||||
void      g_static_rw_lock_free           (GStaticRWLock* lock);
 | 
			
		||||
 | 
			
		||||
/* these are some convenience macros that expand to nothing if GLib
 | 
			
		||||
 * was configured with --disable-threads. for using StaticMutexes,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										178
									
								
								gthread.c
									
									
									
									
									
								
							
							
						
						
									
										178
									
								
								gthread.c
									
									
									
									
									
								
							@@ -52,7 +52,7 @@
 | 
			
		||||
#endif /* GLIB_SIZEOF_SYSTEM_THREAD == SIZEOF_VOID_P */
 | 
			
		||||
 | 
			
		||||
GQuark 
 | 
			
		||||
g_thread_error_quark()
 | 
			
		||||
g_thread_error_quark (void)
 | 
			
		||||
{
 | 
			
		||||
  static GQuark quark;
 | 
			
		||||
  if (!quark)
 | 
			
		||||
@@ -117,8 +117,11 @@ GThreadFunctions g_thread_functions_for_glib_use = {
 | 
			
		||||
/* Local data */
 | 
			
		||||
 | 
			
		||||
static GMutex   *g_mutex_protect_static_mutex_allocation = NULL;
 | 
			
		||||
static GMutex   *g_thread_specific_mutex = NULL;
 | 
			
		||||
static GPrivate *g_thread_specific_private = NULL;
 | 
			
		||||
static GSList   *g_thread_all_threads = NULL;
 | 
			
		||||
static GSList   *g_thread_free_indeces = NULL;
 | 
			
		||||
 | 
			
		||||
G_LOCK_DEFINE_STATIC (g_thread);
 | 
			
		||||
 | 
			
		||||
/* This must be called only once, before any threads are created.
 | 
			
		||||
 * It will only be called from g_thread_init() in -lgthread.
 | 
			
		||||
@@ -137,8 +140,17 @@ g_mutex_init (void)
 | 
			
		||||
  G_THREAD_UF (private_set, (g_thread_specific_private, main_thread));
 | 
			
		||||
  G_THREAD_UF (thread_self, (&main_thread->system_thread));
 | 
			
		||||
 | 
			
		||||
  g_mutex_protect_static_mutex_allocation = g_mutex_new();
 | 
			
		||||
  g_thread_specific_mutex = g_mutex_new();
 | 
			
		||||
  g_mutex_protect_static_mutex_allocation = g_mutex_new ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void 
 | 
			
		||||
g_static_mutex_init (GStaticMutex *mutex)
 | 
			
		||||
{
 | 
			
		||||
  static GStaticMutex init_mutex = G_STATIC_MUTEX_INIT;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (mutex);
 | 
			
		||||
 | 
			
		||||
  memcpy (mutex, &init_mutex, sizeof (GStaticMutex));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GMutex *
 | 
			
		||||
@@ -152,23 +164,13 @@ g_static_mutex_get_mutex_impl (GMutex** mutex)
 | 
			
		||||
  g_mutex_lock (g_mutex_protect_static_mutex_allocation);
 | 
			
		||||
 | 
			
		||||
  if (!(*mutex)) 
 | 
			
		||||
    *mutex = g_mutex_new(); 
 | 
			
		||||
    *mutex = g_mutex_new (); 
 | 
			
		||||
 | 
			
		||||
  g_mutex_unlock (g_mutex_protect_static_mutex_allocation);
 | 
			
		||||
  
 | 
			
		||||
  return *mutex;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void 
 | 
			
		||||
g_static_mutex_init (GStaticMutex *mutex)
 | 
			
		||||
{
 | 
			
		||||
  static GStaticMutex init_mutex = G_STATIC_MUTEX_INIT;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (mutex);
 | 
			
		||||
 | 
			
		||||
  memcpy (mutex, &init_mutex, sizeof (GStaticMutex));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
g_static_mutex_free (GStaticMutex* mutex)
 | 
			
		||||
{
 | 
			
		||||
@@ -186,6 +188,16 @@ g_static_mutex_free (GStaticMutex* mutex)
 | 
			
		||||
  *runtime_mutex = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void     
 | 
			
		||||
g_static_rec_mutex_init (GStaticRecMutex *mutex)
 | 
			
		||||
{
 | 
			
		||||
  static GStaticRecMutex init_mutex = G_STATIC_REC_MUTEX_INIT;
 | 
			
		||||
  
 | 
			
		||||
  g_return_if_fail (mutex);
 | 
			
		||||
 | 
			
		||||
  memcpy (mutex, &init_mutex, sizeof (GStaticRecMutex));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
g_static_rec_mutex_lock (GStaticRecMutex* mutex)
 | 
			
		||||
{
 | 
			
		||||
@@ -284,6 +296,19 @@ g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex)
 | 
			
		||||
  return depth;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
g_static_rec_mutex_free (GStaticRecMutex *mutex)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (mutex);
 | 
			
		||||
 | 
			
		||||
  g_static_mutex_free (&mutex->mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void     
 | 
			
		||||
g_static_private_init (GStaticPrivate *private_key)
 | 
			
		||||
{
 | 
			
		||||
  private_key->index = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gpointer
 | 
			
		||||
g_static_private_get (GStaticPrivate *private_key)
 | 
			
		||||
@@ -343,12 +368,23 @@ g_static_private_set_for_thread (GStaticPrivate *private_key,
 | 
			
		||||
 | 
			
		||||
  if (!private_key->index)
 | 
			
		||||
    {
 | 
			
		||||
      g_mutex_lock (g_thread_specific_mutex);
 | 
			
		||||
      G_LOCK (g_thread);
 | 
			
		||||
 | 
			
		||||
      if (!private_key->index)
 | 
			
		||||
	private_key->index = ++next_index;
 | 
			
		||||
	{
 | 
			
		||||
	  if (g_thread_free_indeces)
 | 
			
		||||
	    {
 | 
			
		||||
	      private_key->index = 
 | 
			
		||||
		GPOINTER_TO_UINT (g_thread_free_indeces->data);
 | 
			
		||||
	      g_thread_free_indeces = 
 | 
			
		||||
		g_slist_delete_link (g_thread_free_indeces,
 | 
			
		||||
				     g_thread_free_indeces);
 | 
			
		||||
	    }
 | 
			
		||||
	  else
 | 
			
		||||
	    private_key->index = ++next_index;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      g_mutex_unlock (g_thread_specific_mutex);
 | 
			
		||||
      G_UNLOCK (g_thread);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (private_key->index > array->len)
 | 
			
		||||
@@ -372,6 +408,35 @@ g_static_private_set_for_thread (GStaticPrivate *private_key,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void     
 | 
			
		||||
g_static_private_free (GStaticPrivate *private_key)
 | 
			
		||||
{
 | 
			
		||||
  GStaticPrivate copied_key;
 | 
			
		||||
  GSList *list;
 | 
			
		||||
 | 
			
		||||
  copied_key.index = private_key->index;
 | 
			
		||||
  private_key->index = 0;
 | 
			
		||||
 | 
			
		||||
  if (!copied_key.index)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  G_LOCK (g_thread);
 | 
			
		||||
  list =  g_thread_all_threads;
 | 
			
		||||
  while (list)
 | 
			
		||||
    {
 | 
			
		||||
      GThread *thread = list->data;
 | 
			
		||||
      list = list->next;
 | 
			
		||||
      
 | 
			
		||||
      G_UNLOCK (g_thread);
 | 
			
		||||
      g_static_private_set_for_thread (&copied_key, thread, NULL, NULL);
 | 
			
		||||
      G_LOCK (g_thread);
 | 
			
		||||
    }
 | 
			
		||||
  g_thread_free_indeces = 
 | 
			
		||||
    g_slist_prepend (g_thread_free_indeces, 
 | 
			
		||||
		     GUINT_TO_POINTER (copied_key.index));
 | 
			
		||||
  G_UNLOCK (g_thread);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_thread_cleanup (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
@@ -396,6 +461,10 @@ g_thread_cleanup (gpointer data)
 | 
			
		||||
         it is, the structure is freed in g_thread_join */
 | 
			
		||||
      if (!thread->thread.joinable)
 | 
			
		||||
	{
 | 
			
		||||
	  G_LOCK (g_thread);
 | 
			
		||||
	  g_thread_all_threads = g_slist_remove (g_thread_all_threads, data);
 | 
			
		||||
	  G_UNLOCK (g_thread);
 | 
			
		||||
	  
 | 
			
		||||
	  /* Just to make sure, this isn't used any more */
 | 
			
		||||
	  g_system_thread_assign (thread->system_thread, zero_thread);
 | 
			
		||||
	  g_free (thread);
 | 
			
		||||
@@ -409,8 +478,6 @@ g_thread_fail (void)
 | 
			
		||||
  g_error ("The thread system is not yet initialized.");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
G_LOCK_DEFINE_STATIC (g_thread_create);
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
g_thread_create_proxy (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
@@ -423,8 +490,8 @@ g_thread_create_proxy (gpointer data)
 | 
			
		||||
 | 
			
		||||
  /* the lock makes sure, that thread->system_thread is written,
 | 
			
		||||
     before thread->func is called. See g_thread_create. */
 | 
			
		||||
  G_LOCK (g_thread_create);
 | 
			
		||||
  G_UNLOCK (g_thread_create);
 | 
			
		||||
  G_LOCK (g_thread);
 | 
			
		||||
  G_UNLOCK (g_thread);
 | 
			
		||||
 | 
			
		||||
  thread->func (thread->arg);
 | 
			
		||||
}
 | 
			
		||||
@@ -450,11 +517,12 @@ g_thread_create (GThreadFunc 		 thread_func,
 | 
			
		||||
  result->func = thread_func;
 | 
			
		||||
  result->arg = arg;
 | 
			
		||||
  result->private_data = NULL; 
 | 
			
		||||
  G_LOCK (g_thread_create);
 | 
			
		||||
  G_LOCK (g_thread);
 | 
			
		||||
  G_THREAD_UF (thread_create, (g_thread_create_proxy, result, 
 | 
			
		||||
			       stack_size, joinable, bound, priority,
 | 
			
		||||
			       &result->system_thread, &local_error));
 | 
			
		||||
  G_UNLOCK (g_thread_create);
 | 
			
		||||
  g_thread_all_threads = g_slist_prepend (g_thread_all_threads, result);
 | 
			
		||||
  G_UNLOCK (g_thread);
 | 
			
		||||
 | 
			
		||||
  if (local_error)
 | 
			
		||||
    {
 | 
			
		||||
@@ -478,6 +546,10 @@ g_thread_join (GThread* thread)
 | 
			
		||||
 | 
			
		||||
  G_THREAD_UF (thread_join, (&real->system_thread));
 | 
			
		||||
 | 
			
		||||
  G_LOCK (g_thread);
 | 
			
		||||
  g_thread_all_threads = g_slist_remove (g_thread_all_threads, thread);
 | 
			
		||||
  G_UNLOCK (g_thread);
 | 
			
		||||
 | 
			
		||||
  /* Just to make sure, this isn't used any more */
 | 
			
		||||
  thread->joinable = 0;
 | 
			
		||||
  g_system_thread_assign (real->system_thread, zero_thread);
 | 
			
		||||
@@ -505,7 +577,7 @@ g_thread_set_priority (GThread* thread,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GThread*
 | 
			
		||||
g_thread_self()
 | 
			
		||||
g_thread_self (void)
 | 
			
		||||
{
 | 
			
		||||
  GRealThread* thread = g_private_get (g_thread_specific_private);
 | 
			
		||||
 | 
			
		||||
@@ -526,20 +598,36 @@ g_thread_self()
 | 
			
		||||
      if (g_thread_supported ())
 | 
			
		||||
	G_THREAD_UF (thread_self, (&thread->system_thread));
 | 
			
		||||
 | 
			
		||||
      g_private_set (g_thread_specific_private, thread);
 | 
			
		||||
      g_private_set (g_thread_specific_private, thread); 
 | 
			
		||||
      
 | 
			
		||||
      G_LOCK (g_thread);
 | 
			
		||||
      g_thread_all_threads = g_slist_prepend (g_thread_all_threads, thread);
 | 
			
		||||
      G_UNLOCK (g_thread);
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return (GThread*)thread;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void inline g_static_rw_lock_wait (GCond** cond, GStaticMutex* mutex)
 | 
			
		||||
void
 | 
			
		||||
g_static_rw_lock_init (GStaticRWLock* lock)
 | 
			
		||||
{
 | 
			
		||||
  static GStaticRWLock init_lock = G_STATIC_RW_LOCK_INIT;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (lock);
 | 
			
		||||
 | 
			
		||||
  memcpy (lock, &init_lock, sizeof (GStaticRWLock));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void inline 
 | 
			
		||||
g_static_rw_lock_wait (GCond** cond, GStaticMutex* mutex)
 | 
			
		||||
{
 | 
			
		||||
  if (!*cond)
 | 
			
		||||
      *cond = g_cond_new ();
 | 
			
		||||
  g_cond_wait (*cond, g_static_mutex_get_mutex (mutex));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void inline g_static_rw_lock_signal (GStaticRWLock* lock)
 | 
			
		||||
static void inline 
 | 
			
		||||
g_static_rw_lock_signal (GStaticRWLock* lock)
 | 
			
		||||
{
 | 
			
		||||
  if (lock->want_to_write && lock->write_cond)
 | 
			
		||||
    g_cond_signal (lock->write_cond);
 | 
			
		||||
@@ -547,7 +635,8 @@ static void inline g_static_rw_lock_signal (GStaticRWLock* lock)
 | 
			
		||||
    g_cond_broadcast (lock->read_cond);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void g_static_rw_lock_reader_lock (GStaticRWLock* lock)
 | 
			
		||||
void 
 | 
			
		||||
g_static_rw_lock_reader_lock (GStaticRWLock* lock)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (lock);
 | 
			
		||||
 | 
			
		||||
@@ -561,7 +650,8 @@ void g_static_rw_lock_reader_lock (GStaticRWLock* lock)
 | 
			
		||||
  g_static_mutex_unlock (&lock->mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean g_static_rw_lock_reader_trylock (GStaticRWLock* lock)
 | 
			
		||||
gboolean 
 | 
			
		||||
g_static_rw_lock_reader_trylock (GStaticRWLock* lock)
 | 
			
		||||
{
 | 
			
		||||
  gboolean ret_val = FALSE;
 | 
			
		||||
 | 
			
		||||
@@ -580,7 +670,8 @@ gboolean g_static_rw_lock_reader_trylock (GStaticRWLock* lock)
 | 
			
		||||
  return ret_val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void g_static_rw_lock_reader_unlock  (GStaticRWLock* lock)
 | 
			
		||||
void 
 | 
			
		||||
g_static_rw_lock_reader_unlock  (GStaticRWLock* lock)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (lock);
 | 
			
		||||
 | 
			
		||||
@@ -594,7 +685,8 @@ void g_static_rw_lock_reader_unlock  (GStaticRWLock* lock)
 | 
			
		||||
  g_static_mutex_unlock (&lock->mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void g_static_rw_lock_writer_lock (GStaticRWLock* lock)
 | 
			
		||||
void 
 | 
			
		||||
g_static_rw_lock_writer_lock (GStaticRWLock* lock)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (lock);
 | 
			
		||||
 | 
			
		||||
@@ -610,7 +702,8 @@ void g_static_rw_lock_writer_lock (GStaticRWLock* lock)
 | 
			
		||||
  g_static_mutex_unlock (&lock->mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean g_static_rw_lock_writer_trylock (GStaticRWLock* lock)
 | 
			
		||||
gboolean 
 | 
			
		||||
g_static_rw_lock_writer_trylock (GStaticRWLock* lock)
 | 
			
		||||
{
 | 
			
		||||
  gboolean ret_val = FALSE;
 | 
			
		||||
 | 
			
		||||
@@ -629,7 +722,8 @@ gboolean g_static_rw_lock_writer_trylock (GStaticRWLock* lock)
 | 
			
		||||
  return ret_val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void g_static_rw_lock_writer_unlock (GStaticRWLock* lock)
 | 
			
		||||
void 
 | 
			
		||||
g_static_rw_lock_writer_unlock (GStaticRWLock* lock)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (lock);
 | 
			
		||||
  
 | 
			
		||||
@@ -642,14 +736,20 @@ void g_static_rw_lock_writer_unlock (GStaticRWLock* lock)
 | 
			
		||||
  g_static_mutex_unlock (&lock->mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void g_static_rw_lock_free (GStaticRWLock* lock)
 | 
			
		||||
void 
 | 
			
		||||
g_static_rw_lock_free (GStaticRWLock* lock)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (lock);
 | 
			
		||||
  
 | 
			
		||||
  if (lock->read_cond)
 | 
			
		||||
    g_cond_free (lock->read_cond);
 | 
			
		||||
    {
 | 
			
		||||
      g_cond_free (lock->read_cond);
 | 
			
		||||
      lock->read_cond = NULL;
 | 
			
		||||
    }
 | 
			
		||||
  if (lock->write_cond)
 | 
			
		||||
    g_cond_free (lock->write_cond);
 | 
			
		||||
  
 | 
			
		||||
    {
 | 
			
		||||
      g_cond_free (lock->write_cond);
 | 
			
		||||
      lock->write_cond = NULL;
 | 
			
		||||
    }
 | 
			
		||||
  g_static_mutex_free (&lock->mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										31
									
								
								gthread.h
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								gthread.h
									
									
									
									
									
								
							@@ -46,8 +46,8 @@ G_BEGIN_DECLS
 | 
			
		||||
/* GLib Thread support
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
extern GQuark g_thread_error_quark();
 | 
			
		||||
#define G_THREAD_ERROR g_thread_error_quark()
 | 
			
		||||
extern GQuark g_thread_error_quark (void);
 | 
			
		||||
#define G_THREAD_ERROR g_thread_error_quark ()
 | 
			
		||||
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
@@ -235,16 +235,18 @@ struct _GStaticPrivate
 | 
			
		||||
  guint index;
 | 
			
		||||
};
 | 
			
		||||
#define G_STATIC_PRIVATE_INIT { 0 }
 | 
			
		||||
gpointer g_static_private_get (GStaticPrivate   *private_key);
 | 
			
		||||
void     g_static_private_set (GStaticPrivate   *private_key,
 | 
			
		||||
                               gpointer          data,
 | 
			
		||||
                               GDestroyNotify    notify);
 | 
			
		||||
gpointer g_static_private_get_for_thread (GStaticPrivate *private_key,
 | 
			
		||||
                                          GThread        *thread);
 | 
			
		||||
void g_static_private_set_for_thread (GStaticPrivate *private_key,
 | 
			
		||||
                                      GThread        *thread,
 | 
			
		||||
                                      gpointer        data,
 | 
			
		||||
                                      GDestroyNotify  notify);
 | 
			
		||||
void     g_static_private_init           (GStaticPrivate   *private_key);
 | 
			
		||||
gpointer g_static_private_get            (GStaticPrivate   *private_key);
 | 
			
		||||
void     g_static_private_set            (GStaticPrivate   *private_key,
 | 
			
		||||
					  gpointer          data,
 | 
			
		||||
					  GDestroyNotify    notify);
 | 
			
		||||
gpointer g_static_private_get_for_thread (GStaticPrivate   *private_key,
 | 
			
		||||
                                          GThread          *thread);
 | 
			
		||||
void     g_static_private_set_for_thread (GStaticPrivate   *private_key,
 | 
			
		||||
					  GThread          *thread,
 | 
			
		||||
					  gpointer          data,
 | 
			
		||||
					  GDestroyNotify    notify);
 | 
			
		||||
void     g_static_private_free           (GStaticPrivate   *private_key);
 | 
			
		||||
 | 
			
		||||
typedef struct _GStaticRecMutex GStaticRecMutex;
 | 
			
		||||
struct _GStaticRecMutex
 | 
			
		||||
@@ -255,12 +257,14 @@ struct _GStaticRecMutex
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define G_STATIC_REC_MUTEX_INIT { G_STATIC_MUTEX_INIT }
 | 
			
		||||
void     g_static_rec_mutex_init        (GStaticRecMutex *mutex);
 | 
			
		||||
void     g_static_rec_mutex_lock        (GStaticRecMutex *mutex);
 | 
			
		||||
gboolean g_static_rec_mutex_trylock     (GStaticRecMutex *mutex);
 | 
			
		||||
void     g_static_rec_mutex_unlock      (GStaticRecMutex *mutex);
 | 
			
		||||
void     g_static_rec_mutex_lock_full   (GStaticRecMutex *mutex,
 | 
			
		||||
                                         guint            depth);
 | 
			
		||||
guint    g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex);
 | 
			
		||||
void     g_static_rec_mutex_free        (GStaticRecMutex *mutex);
 | 
			
		||||
 | 
			
		||||
typedef struct _GStaticRWLock GStaticRWLock;
 | 
			
		||||
struct _GStaticRWLock
 | 
			
		||||
@@ -275,13 +279,14 @@ struct _GStaticRWLock
 | 
			
		||||
 | 
			
		||||
#define G_STATIC_RW_LOCK_INIT { G_STATIC_MUTEX_INIT, NULL, NULL, 0, FALSE, FALSE }
 | 
			
		||||
 | 
			
		||||
void      g_static_rw_lock_init           (GStaticRWLock* lock);
 | 
			
		||||
void      g_static_rw_lock_reader_lock    (GStaticRWLock* lock);
 | 
			
		||||
gboolean  g_static_rw_lock_reader_trylock (GStaticRWLock* lock);
 | 
			
		||||
void      g_static_rw_lock_reader_unlock  (GStaticRWLock* lock);
 | 
			
		||||
void      g_static_rw_lock_writer_lock    (GStaticRWLock* lock);
 | 
			
		||||
gboolean  g_static_rw_lock_writer_trylock (GStaticRWLock* lock);
 | 
			
		||||
void      g_static_rw_lock_writer_unlock  (GStaticRWLock* lock);
 | 
			
		||||
void      g_static_rw_lock_free (GStaticRWLock* lock);
 | 
			
		||||
void      g_static_rw_lock_free           (GStaticRWLock* lock);
 | 
			
		||||
 | 
			
		||||
/* these are some convenience macros that expand to nothing if GLib
 | 
			
		||||
 * was configured with --disable-threads. for using StaticMutexes,
 | 
			
		||||
 
 | 
			
		||||
@@ -81,9 +81,11 @@ test_g_static_rec_mutex (void)
 | 
			
		||||
 | 
			
		||||
#define THREADS 10
 | 
			
		||||
 | 
			
		||||
static GStaticPrivate test_g_static_private_private = G_STATIC_PRIVATE_INIT;
 | 
			
		||||
static GStaticPrivate test_g_static_private_private1 = G_STATIC_PRIVATE_INIT;
 | 
			
		||||
static GStaticPrivate test_g_static_private_private2 = G_STATIC_PRIVATE_INIT;
 | 
			
		||||
static GStaticMutex test_g_static_private_mutex = G_STATIC_MUTEX_INIT;
 | 
			
		||||
static guint test_g_static_private_counter = 0;
 | 
			
		||||
static guint test_g_static_private_ready = 0;
 | 
			
		||||
 | 
			
		||||
static gpointer
 | 
			
		||||
test_g_static_private_constructor (void)
 | 
			
		||||
@@ -109,20 +111,51 @@ test_g_static_private_thread (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  guint number = GPOINTER_TO_INT (data);
 | 
			
		||||
  guint i;
 | 
			
		||||
  guint* private;
 | 
			
		||||
  guint *private1, *private2;
 | 
			
		||||
  for (i = 0; i < 10; i++)
 | 
			
		||||
    {
 | 
			
		||||
      number = number * 11 + 1; /* A very simple and bad RNG ;-) */
 | 
			
		||||
      private = g_static_private_get (&test_g_static_private_private);
 | 
			
		||||
      if (!private || number % 7 > 3)
 | 
			
		||||
      private1 = g_static_private_get (&test_g_static_private_private1);
 | 
			
		||||
      if (!private1 || number % 7 > 3)
 | 
			
		||||
	{
 | 
			
		||||
	  private = test_g_static_private_constructor ();
 | 
			
		||||
	  g_static_private_set (&test_g_static_private_private, private,
 | 
			
		||||
	  private1 = test_g_static_private_constructor ();
 | 
			
		||||
	  g_static_private_set (&test_g_static_private_private1, private1,
 | 
			
		||||
				test_g_static_private_destructor);
 | 
			
		||||
	}
 | 
			
		||||
      *private = number;
 | 
			
		||||
      *private1 = number;
 | 
			
		||||
      private2 = g_static_private_get (&test_g_static_private_private2);
 | 
			
		||||
      if (!private2 || number % 13 > 5)
 | 
			
		||||
	{
 | 
			
		||||
	  private2 = test_g_static_private_constructor ();
 | 
			
		||||
	  g_static_private_set (&test_g_static_private_private2, private2,
 | 
			
		||||
				test_g_static_private_destructor);
 | 
			
		||||
	}
 | 
			
		||||
      *private2 = number * 2;
 | 
			
		||||
      g_usleep (G_USEC_PER_SEC / 5);
 | 
			
		||||
      g_assert (number == *private);
 | 
			
		||||
      g_assert (number == *private1);
 | 
			
		||||
      g_assert (number * 2 == *private2);      
 | 
			
		||||
    }
 | 
			
		||||
  g_static_mutex_lock (&test_g_static_private_mutex);
 | 
			
		||||
  test_g_static_private_ready++;
 | 
			
		||||
  g_static_mutex_unlock (&test_g_static_private_mutex);  
 | 
			
		||||
 | 
			
		||||
  /* Busy wait is not nice but that's just a test */
 | 
			
		||||
  while (test_g_static_private_ready != 0)
 | 
			
		||||
    g_usleep (G_USEC_PER_SEC / 5);  
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < 10; i++)
 | 
			
		||||
    {
 | 
			
		||||
      private2 = g_static_private_get (&test_g_static_private_private2);
 | 
			
		||||
      number = number * 11 + 1; /* A very simple and bad RNG ;-) */
 | 
			
		||||
      if (!private2 || number % 13 > 5)
 | 
			
		||||
	{
 | 
			
		||||
	  private2 = test_g_static_private_constructor ();
 | 
			
		||||
	  g_static_private_set (&test_g_static_private_private2, private2,
 | 
			
		||||
				test_g_static_private_destructor);
 | 
			
		||||
	}      
 | 
			
		||||
      *private2 = number * 2;
 | 
			
		||||
      g_usleep (G_USEC_PER_SEC / 5);
 | 
			
		||||
      g_assert (number * 2 == *private2);      
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -131,6 +164,9 @@ test_g_static_private (void)
 | 
			
		||||
{
 | 
			
		||||
  GThread *threads[THREADS];
 | 
			
		||||
  guint i;
 | 
			
		||||
 | 
			
		||||
  test_g_static_private_ready = 0;
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < THREADS; i++)
 | 
			
		||||
    {
 | 
			
		||||
      threads[i] = g_thread_create (test_g_static_private_thread, 
 | 
			
		||||
@@ -138,6 +174,17 @@ test_g_static_private (void)
 | 
			
		||||
				    0, TRUE, TRUE, 
 | 
			
		||||
				    G_THREAD_PRIORITY_NORMAL, NULL);      
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* Busy wait is not nice but that's just a test */
 | 
			
		||||
  while (test_g_static_private_ready != THREADS)
 | 
			
		||||
    g_usleep (G_USEC_PER_SEC / 5);
 | 
			
		||||
 | 
			
		||||
  /* Reuse the static private */
 | 
			
		||||
  g_static_private_free (&test_g_static_private_private2);
 | 
			
		||||
  g_static_private_init (&test_g_static_private_private2);
 | 
			
		||||
  
 | 
			
		||||
  test_g_static_private_ready = 0;
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < THREADS; i++)
 | 
			
		||||
    {
 | 
			
		||||
      g_thread_join (threads[i]);
 | 
			
		||||
@@ -231,7 +278,7 @@ run_all_tests()
 | 
			
		||||
  test_g_mutex ();
 | 
			
		||||
  test_g_static_rec_mutex ();
 | 
			
		||||
  test_g_static_private ();
 | 
			
		||||
  test_g_static_rw_lock ();  
 | 
			
		||||
  test_g_static_rw_lock ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int 
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user