mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-05-02 12:06:53 +02: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:
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>
|
Mon Feb 12 15:01:09 2001 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* configure.in (gtk_doc_min_version): Add check for gtk-doc version.
|
* 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>
|
Mon Feb 12 15:01:09 2001 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* configure.in (gtk_doc_min_version): Add check for gtk-doc version.
|
* 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>
|
Mon Feb 12 15:01:09 2001 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* configure.in (gtk_doc_min_version): Add check for gtk-doc version.
|
* 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>
|
Mon Feb 12 15:01:09 2001 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* configure.in (gtk_doc_min_version): Add check for gtk-doc version.
|
* 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>
|
Mon Feb 12 15:01:09 2001 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* configure.in (gtk_doc_min_version): Add check for gtk-doc version.
|
* 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>
|
Mon Feb 12 15:01:09 2001 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* configure.in (gtk_doc_min_version): Add check for gtk-doc version.
|
* 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>
|
Mon Feb 12 15:01:09 2001 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* configure.in (gtk_doc_min_version): Add check for gtk-doc version.
|
* 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>
|
Mon Feb 12 15:01:09 2001 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* configure.in (gtk_doc_min_version): Add check for gtk-doc version.
|
* 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 */
|
#endif /* GLIB_SIZEOF_SYSTEM_THREAD == SIZEOF_VOID_P */
|
||||||
|
|
||||||
GQuark
|
GQuark
|
||||||
g_thread_error_quark()
|
g_thread_error_quark (void)
|
||||||
{
|
{
|
||||||
static GQuark quark;
|
static GQuark quark;
|
||||||
if (!quark)
|
if (!quark)
|
||||||
@ -117,8 +117,11 @@ GThreadFunctions g_thread_functions_for_glib_use = {
|
|||||||
/* Local data */
|
/* Local data */
|
||||||
|
|
||||||
static GMutex *g_mutex_protect_static_mutex_allocation = NULL;
|
static GMutex *g_mutex_protect_static_mutex_allocation = NULL;
|
||||||
static GMutex *g_thread_specific_mutex = NULL;
|
|
||||||
static GPrivate *g_thread_specific_private = 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.
|
/* This must be called only once, before any threads are created.
|
||||||
* It will only be called from g_thread_init() in -lgthread.
|
* 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 (private_set, (g_thread_specific_private, main_thread));
|
||||||
G_THREAD_UF (thread_self, (&main_thread->system_thread));
|
G_THREAD_UF (thread_self, (&main_thread->system_thread));
|
||||||
|
|
||||||
g_mutex_protect_static_mutex_allocation = g_mutex_new();
|
g_mutex_protect_static_mutex_allocation = g_mutex_new ();
|
||||||
g_thread_specific_mutex = 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 *
|
GMutex *
|
||||||
@ -152,23 +164,13 @@ g_static_mutex_get_mutex_impl (GMutex** mutex)
|
|||||||
g_mutex_lock (g_mutex_protect_static_mutex_allocation);
|
g_mutex_lock (g_mutex_protect_static_mutex_allocation);
|
||||||
|
|
||||||
if (!(*mutex))
|
if (!(*mutex))
|
||||||
*mutex = g_mutex_new();
|
*mutex = g_mutex_new ();
|
||||||
|
|
||||||
g_mutex_unlock (g_mutex_protect_static_mutex_allocation);
|
g_mutex_unlock (g_mutex_protect_static_mutex_allocation);
|
||||||
|
|
||||||
return *mutex;
|
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
|
void
|
||||||
g_static_mutex_free (GStaticMutex* mutex)
|
g_static_mutex_free (GStaticMutex* mutex)
|
||||||
{
|
{
|
||||||
@ -186,6 +188,16 @@ g_static_mutex_free (GStaticMutex* mutex)
|
|||||||
*runtime_mutex = NULL;
|
*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
|
void
|
||||||
g_static_rec_mutex_lock (GStaticRecMutex* mutex)
|
g_static_rec_mutex_lock (GStaticRecMutex* mutex)
|
||||||
{
|
{
|
||||||
@ -284,6 +296,19 @@ g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex)
|
|||||||
return depth;
|
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
|
gpointer
|
||||||
g_static_private_get (GStaticPrivate *private_key)
|
g_static_private_get (GStaticPrivate *private_key)
|
||||||
@ -343,12 +368,23 @@ g_static_private_set_for_thread (GStaticPrivate *private_key,
|
|||||||
|
|
||||||
if (!private_key->index)
|
if (!private_key->index)
|
||||||
{
|
{
|
||||||
g_mutex_lock (g_thread_specific_mutex);
|
G_LOCK (g_thread);
|
||||||
|
|
||||||
if (!private_key->index)
|
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)
|
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
|
static void
|
||||||
g_thread_cleanup (gpointer data)
|
g_thread_cleanup (gpointer data)
|
||||||
{
|
{
|
||||||
@ -396,6 +461,10 @@ g_thread_cleanup (gpointer data)
|
|||||||
it is, the structure is freed in g_thread_join */
|
it is, the structure is freed in g_thread_join */
|
||||||
if (!thread->thread.joinable)
|
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 */
|
/* Just to make sure, this isn't used any more */
|
||||||
g_system_thread_assign (thread->system_thread, zero_thread);
|
g_system_thread_assign (thread->system_thread, zero_thread);
|
||||||
g_free (thread);
|
g_free (thread);
|
||||||
@ -409,8 +478,6 @@ g_thread_fail (void)
|
|||||||
g_error ("The thread system is not yet initialized.");
|
g_error ("The thread system is not yet initialized.");
|
||||||
}
|
}
|
||||||
|
|
||||||
G_LOCK_DEFINE_STATIC (g_thread_create);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_thread_create_proxy (gpointer data)
|
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,
|
/* the lock makes sure, that thread->system_thread is written,
|
||||||
before thread->func is called. See g_thread_create. */
|
before thread->func is called. See g_thread_create. */
|
||||||
G_LOCK (g_thread_create);
|
G_LOCK (g_thread);
|
||||||
G_UNLOCK (g_thread_create);
|
G_UNLOCK (g_thread);
|
||||||
|
|
||||||
thread->func (thread->arg);
|
thread->func (thread->arg);
|
||||||
}
|
}
|
||||||
@ -450,11 +517,12 @@ g_thread_create (GThreadFunc thread_func,
|
|||||||
result->func = thread_func;
|
result->func = thread_func;
|
||||||
result->arg = arg;
|
result->arg = arg;
|
||||||
result->private_data = NULL;
|
result->private_data = NULL;
|
||||||
G_LOCK (g_thread_create);
|
G_LOCK (g_thread);
|
||||||
G_THREAD_UF (thread_create, (g_thread_create_proxy, result,
|
G_THREAD_UF (thread_create, (g_thread_create_proxy, result,
|
||||||
stack_size, joinable, bound, priority,
|
stack_size, joinable, bound, priority,
|
||||||
&result->system_thread, &local_error));
|
&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)
|
if (local_error)
|
||||||
{
|
{
|
||||||
@ -478,6 +546,10 @@ g_thread_join (GThread* thread)
|
|||||||
|
|
||||||
G_THREAD_UF (thread_join, (&real->system_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 */
|
/* Just to make sure, this isn't used any more */
|
||||||
thread->joinable = 0;
|
thread->joinable = 0;
|
||||||
g_system_thread_assign (real->system_thread, zero_thread);
|
g_system_thread_assign (real->system_thread, zero_thread);
|
||||||
@ -505,7 +577,7 @@ g_thread_set_priority (GThread* thread,
|
|||||||
}
|
}
|
||||||
|
|
||||||
GThread*
|
GThread*
|
||||||
g_thread_self()
|
g_thread_self (void)
|
||||||
{
|
{
|
||||||
GRealThread* thread = g_private_get (g_thread_specific_private);
|
GRealThread* thread = g_private_get (g_thread_specific_private);
|
||||||
|
|
||||||
@ -526,20 +598,36 @@ g_thread_self()
|
|||||||
if (g_thread_supported ())
|
if (g_thread_supported ())
|
||||||
G_THREAD_UF (thread_self, (&thread->system_thread));
|
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;
|
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)
|
if (!*cond)
|
||||||
*cond = g_cond_new ();
|
*cond = g_cond_new ();
|
||||||
g_cond_wait (*cond, g_static_mutex_get_mutex (mutex));
|
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)
|
if (lock->want_to_write && lock->write_cond)
|
||||||
g_cond_signal (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);
|
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);
|
g_return_if_fail (lock);
|
||||||
|
|
||||||
@ -561,7 +650,8 @@ void g_static_rw_lock_reader_lock (GStaticRWLock* lock)
|
|||||||
g_static_mutex_unlock (&lock->mutex);
|
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;
|
gboolean ret_val = FALSE;
|
||||||
|
|
||||||
@ -580,7 +670,8 @@ gboolean g_static_rw_lock_reader_trylock (GStaticRWLock* lock)
|
|||||||
return ret_val;
|
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);
|
g_return_if_fail (lock);
|
||||||
|
|
||||||
@ -594,7 +685,8 @@ void g_static_rw_lock_reader_unlock (GStaticRWLock* lock)
|
|||||||
g_static_mutex_unlock (&lock->mutex);
|
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);
|
g_return_if_fail (lock);
|
||||||
|
|
||||||
@ -610,7 +702,8 @@ void g_static_rw_lock_writer_lock (GStaticRWLock* lock)
|
|||||||
g_static_mutex_unlock (&lock->mutex);
|
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;
|
gboolean ret_val = FALSE;
|
||||||
|
|
||||||
@ -629,7 +722,8 @@ gboolean g_static_rw_lock_writer_trylock (GStaticRWLock* lock)
|
|||||||
return ret_val;
|
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);
|
g_return_if_fail (lock);
|
||||||
|
|
||||||
@ -642,14 +736,20 @@ void g_static_rw_lock_writer_unlock (GStaticRWLock* lock)
|
|||||||
g_static_mutex_unlock (&lock->mutex);
|
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);
|
g_return_if_fail (lock);
|
||||||
|
|
||||||
if (lock->read_cond)
|
if (lock->read_cond)
|
||||||
g_cond_free (lock->read_cond);
|
{
|
||||||
|
g_cond_free (lock->read_cond);
|
||||||
|
lock->read_cond = NULL;
|
||||||
|
}
|
||||||
if (lock->write_cond)
|
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
|
/* GLib Thread support
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern GQuark g_thread_error_quark();
|
extern GQuark g_thread_error_quark (void);
|
||||||
#define G_THREAD_ERROR g_thread_error_quark()
|
#define G_THREAD_ERROR g_thread_error_quark ()
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
@ -235,16 +235,18 @@ struct _GStaticPrivate
|
|||||||
guint index;
|
guint index;
|
||||||
};
|
};
|
||||||
#define G_STATIC_PRIVATE_INIT { 0 }
|
#define G_STATIC_PRIVATE_INIT { 0 }
|
||||||
gpointer g_static_private_get (GStaticPrivate *private_key);
|
void g_static_private_init (GStaticPrivate *private_key);
|
||||||
void g_static_private_set (GStaticPrivate *private_key,
|
gpointer g_static_private_get (GStaticPrivate *private_key);
|
||||||
gpointer data,
|
void g_static_private_set (GStaticPrivate *private_key,
|
||||||
GDestroyNotify notify);
|
gpointer data,
|
||||||
gpointer g_static_private_get_for_thread (GStaticPrivate *private_key,
|
GDestroyNotify notify);
|
||||||
GThread *thread);
|
gpointer g_static_private_get_for_thread (GStaticPrivate *private_key,
|
||||||
void g_static_private_set_for_thread (GStaticPrivate *private_key,
|
GThread *thread);
|
||||||
GThread *thread,
|
void g_static_private_set_for_thread (GStaticPrivate *private_key,
|
||||||
gpointer data,
|
GThread *thread,
|
||||||
GDestroyNotify notify);
|
gpointer data,
|
||||||
|
GDestroyNotify notify);
|
||||||
|
void g_static_private_free (GStaticPrivate *private_key);
|
||||||
|
|
||||||
typedef struct _GStaticRecMutex GStaticRecMutex;
|
typedef struct _GStaticRecMutex GStaticRecMutex;
|
||||||
struct _GStaticRecMutex
|
struct _GStaticRecMutex
|
||||||
@ -255,12 +257,14 @@ struct _GStaticRecMutex
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define G_STATIC_REC_MUTEX_INIT { G_STATIC_MUTEX_INIT }
|
#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);
|
void g_static_rec_mutex_lock (GStaticRecMutex *mutex);
|
||||||
gboolean g_static_rec_mutex_trylock (GStaticRecMutex *mutex);
|
gboolean g_static_rec_mutex_trylock (GStaticRecMutex *mutex);
|
||||||
void g_static_rec_mutex_unlock (GStaticRecMutex *mutex);
|
void g_static_rec_mutex_unlock (GStaticRecMutex *mutex);
|
||||||
void g_static_rec_mutex_lock_full (GStaticRecMutex *mutex,
|
void g_static_rec_mutex_lock_full (GStaticRecMutex *mutex,
|
||||||
guint depth);
|
guint depth);
|
||||||
guint g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex);
|
guint g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex);
|
||||||
|
void g_static_rec_mutex_free (GStaticRecMutex *mutex);
|
||||||
|
|
||||||
typedef struct _GStaticRWLock GStaticRWLock;
|
typedef struct _GStaticRWLock GStaticRWLock;
|
||||||
struct _GStaticRWLock
|
struct _GStaticRWLock
|
||||||
@ -275,13 +279,14 @@ struct _GStaticRWLock
|
|||||||
|
|
||||||
#define G_STATIC_RW_LOCK_INIT { G_STATIC_MUTEX_INIT, NULL, NULL, 0, FALSE, FALSE }
|
#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);
|
void g_static_rw_lock_reader_lock (GStaticRWLock* lock);
|
||||||
gboolean g_static_rw_lock_reader_trylock (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_reader_unlock (GStaticRWLock* lock);
|
||||||
void g_static_rw_lock_writer_lock (GStaticRWLock* lock);
|
void g_static_rw_lock_writer_lock (GStaticRWLock* lock);
|
||||||
gboolean g_static_rw_lock_writer_trylock (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_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
|
/* these are some convenience macros that expand to nothing if GLib
|
||||||
* was configured with --disable-threads. for using StaticMutexes,
|
* 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 */
|
#endif /* GLIB_SIZEOF_SYSTEM_THREAD == SIZEOF_VOID_P */
|
||||||
|
|
||||||
GQuark
|
GQuark
|
||||||
g_thread_error_quark()
|
g_thread_error_quark (void)
|
||||||
{
|
{
|
||||||
static GQuark quark;
|
static GQuark quark;
|
||||||
if (!quark)
|
if (!quark)
|
||||||
@ -117,8 +117,11 @@ GThreadFunctions g_thread_functions_for_glib_use = {
|
|||||||
/* Local data */
|
/* Local data */
|
||||||
|
|
||||||
static GMutex *g_mutex_protect_static_mutex_allocation = NULL;
|
static GMutex *g_mutex_protect_static_mutex_allocation = NULL;
|
||||||
static GMutex *g_thread_specific_mutex = NULL;
|
|
||||||
static GPrivate *g_thread_specific_private = 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.
|
/* This must be called only once, before any threads are created.
|
||||||
* It will only be called from g_thread_init() in -lgthread.
|
* 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 (private_set, (g_thread_specific_private, main_thread));
|
||||||
G_THREAD_UF (thread_self, (&main_thread->system_thread));
|
G_THREAD_UF (thread_self, (&main_thread->system_thread));
|
||||||
|
|
||||||
g_mutex_protect_static_mutex_allocation = g_mutex_new();
|
g_mutex_protect_static_mutex_allocation = g_mutex_new ();
|
||||||
g_thread_specific_mutex = 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 *
|
GMutex *
|
||||||
@ -152,23 +164,13 @@ g_static_mutex_get_mutex_impl (GMutex** mutex)
|
|||||||
g_mutex_lock (g_mutex_protect_static_mutex_allocation);
|
g_mutex_lock (g_mutex_protect_static_mutex_allocation);
|
||||||
|
|
||||||
if (!(*mutex))
|
if (!(*mutex))
|
||||||
*mutex = g_mutex_new();
|
*mutex = g_mutex_new ();
|
||||||
|
|
||||||
g_mutex_unlock (g_mutex_protect_static_mutex_allocation);
|
g_mutex_unlock (g_mutex_protect_static_mutex_allocation);
|
||||||
|
|
||||||
return *mutex;
|
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
|
void
|
||||||
g_static_mutex_free (GStaticMutex* mutex)
|
g_static_mutex_free (GStaticMutex* mutex)
|
||||||
{
|
{
|
||||||
@ -186,6 +188,16 @@ g_static_mutex_free (GStaticMutex* mutex)
|
|||||||
*runtime_mutex = NULL;
|
*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
|
void
|
||||||
g_static_rec_mutex_lock (GStaticRecMutex* mutex)
|
g_static_rec_mutex_lock (GStaticRecMutex* mutex)
|
||||||
{
|
{
|
||||||
@ -284,6 +296,19 @@ g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex)
|
|||||||
return depth;
|
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
|
gpointer
|
||||||
g_static_private_get (GStaticPrivate *private_key)
|
g_static_private_get (GStaticPrivate *private_key)
|
||||||
@ -343,12 +368,23 @@ g_static_private_set_for_thread (GStaticPrivate *private_key,
|
|||||||
|
|
||||||
if (!private_key->index)
|
if (!private_key->index)
|
||||||
{
|
{
|
||||||
g_mutex_lock (g_thread_specific_mutex);
|
G_LOCK (g_thread);
|
||||||
|
|
||||||
if (!private_key->index)
|
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)
|
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
|
static void
|
||||||
g_thread_cleanup (gpointer data)
|
g_thread_cleanup (gpointer data)
|
||||||
{
|
{
|
||||||
@ -396,6 +461,10 @@ g_thread_cleanup (gpointer data)
|
|||||||
it is, the structure is freed in g_thread_join */
|
it is, the structure is freed in g_thread_join */
|
||||||
if (!thread->thread.joinable)
|
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 */
|
/* Just to make sure, this isn't used any more */
|
||||||
g_system_thread_assign (thread->system_thread, zero_thread);
|
g_system_thread_assign (thread->system_thread, zero_thread);
|
||||||
g_free (thread);
|
g_free (thread);
|
||||||
@ -409,8 +478,6 @@ g_thread_fail (void)
|
|||||||
g_error ("The thread system is not yet initialized.");
|
g_error ("The thread system is not yet initialized.");
|
||||||
}
|
}
|
||||||
|
|
||||||
G_LOCK_DEFINE_STATIC (g_thread_create);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
g_thread_create_proxy (gpointer data)
|
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,
|
/* the lock makes sure, that thread->system_thread is written,
|
||||||
before thread->func is called. See g_thread_create. */
|
before thread->func is called. See g_thread_create. */
|
||||||
G_LOCK (g_thread_create);
|
G_LOCK (g_thread);
|
||||||
G_UNLOCK (g_thread_create);
|
G_UNLOCK (g_thread);
|
||||||
|
|
||||||
thread->func (thread->arg);
|
thread->func (thread->arg);
|
||||||
}
|
}
|
||||||
@ -450,11 +517,12 @@ g_thread_create (GThreadFunc thread_func,
|
|||||||
result->func = thread_func;
|
result->func = thread_func;
|
||||||
result->arg = arg;
|
result->arg = arg;
|
||||||
result->private_data = NULL;
|
result->private_data = NULL;
|
||||||
G_LOCK (g_thread_create);
|
G_LOCK (g_thread);
|
||||||
G_THREAD_UF (thread_create, (g_thread_create_proxy, result,
|
G_THREAD_UF (thread_create, (g_thread_create_proxy, result,
|
||||||
stack_size, joinable, bound, priority,
|
stack_size, joinable, bound, priority,
|
||||||
&result->system_thread, &local_error));
|
&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)
|
if (local_error)
|
||||||
{
|
{
|
||||||
@ -478,6 +546,10 @@ g_thread_join (GThread* thread)
|
|||||||
|
|
||||||
G_THREAD_UF (thread_join, (&real->system_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 */
|
/* Just to make sure, this isn't used any more */
|
||||||
thread->joinable = 0;
|
thread->joinable = 0;
|
||||||
g_system_thread_assign (real->system_thread, zero_thread);
|
g_system_thread_assign (real->system_thread, zero_thread);
|
||||||
@ -505,7 +577,7 @@ g_thread_set_priority (GThread* thread,
|
|||||||
}
|
}
|
||||||
|
|
||||||
GThread*
|
GThread*
|
||||||
g_thread_self()
|
g_thread_self (void)
|
||||||
{
|
{
|
||||||
GRealThread* thread = g_private_get (g_thread_specific_private);
|
GRealThread* thread = g_private_get (g_thread_specific_private);
|
||||||
|
|
||||||
@ -526,20 +598,36 @@ g_thread_self()
|
|||||||
if (g_thread_supported ())
|
if (g_thread_supported ())
|
||||||
G_THREAD_UF (thread_self, (&thread->system_thread));
|
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;
|
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)
|
if (!*cond)
|
||||||
*cond = g_cond_new ();
|
*cond = g_cond_new ();
|
||||||
g_cond_wait (*cond, g_static_mutex_get_mutex (mutex));
|
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)
|
if (lock->want_to_write && lock->write_cond)
|
||||||
g_cond_signal (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);
|
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);
|
g_return_if_fail (lock);
|
||||||
|
|
||||||
@ -561,7 +650,8 @@ void g_static_rw_lock_reader_lock (GStaticRWLock* lock)
|
|||||||
g_static_mutex_unlock (&lock->mutex);
|
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;
|
gboolean ret_val = FALSE;
|
||||||
|
|
||||||
@ -580,7 +670,8 @@ gboolean g_static_rw_lock_reader_trylock (GStaticRWLock* lock)
|
|||||||
return ret_val;
|
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);
|
g_return_if_fail (lock);
|
||||||
|
|
||||||
@ -594,7 +685,8 @@ void g_static_rw_lock_reader_unlock (GStaticRWLock* lock)
|
|||||||
g_static_mutex_unlock (&lock->mutex);
|
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);
|
g_return_if_fail (lock);
|
||||||
|
|
||||||
@ -610,7 +702,8 @@ void g_static_rw_lock_writer_lock (GStaticRWLock* lock)
|
|||||||
g_static_mutex_unlock (&lock->mutex);
|
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;
|
gboolean ret_val = FALSE;
|
||||||
|
|
||||||
@ -629,7 +722,8 @@ gboolean g_static_rw_lock_writer_trylock (GStaticRWLock* lock)
|
|||||||
return ret_val;
|
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);
|
g_return_if_fail (lock);
|
||||||
|
|
||||||
@ -642,14 +736,20 @@ void g_static_rw_lock_writer_unlock (GStaticRWLock* lock)
|
|||||||
g_static_mutex_unlock (&lock->mutex);
|
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);
|
g_return_if_fail (lock);
|
||||||
|
|
||||||
if (lock->read_cond)
|
if (lock->read_cond)
|
||||||
g_cond_free (lock->read_cond);
|
{
|
||||||
|
g_cond_free (lock->read_cond);
|
||||||
|
lock->read_cond = NULL;
|
||||||
|
}
|
||||||
if (lock->write_cond)
|
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
|
/* GLib Thread support
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern GQuark g_thread_error_quark();
|
extern GQuark g_thread_error_quark (void);
|
||||||
#define G_THREAD_ERROR g_thread_error_quark()
|
#define G_THREAD_ERROR g_thread_error_quark ()
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
@ -235,16 +235,18 @@ struct _GStaticPrivate
|
|||||||
guint index;
|
guint index;
|
||||||
};
|
};
|
||||||
#define G_STATIC_PRIVATE_INIT { 0 }
|
#define G_STATIC_PRIVATE_INIT { 0 }
|
||||||
gpointer g_static_private_get (GStaticPrivate *private_key);
|
void g_static_private_init (GStaticPrivate *private_key);
|
||||||
void g_static_private_set (GStaticPrivate *private_key,
|
gpointer g_static_private_get (GStaticPrivate *private_key);
|
||||||
gpointer data,
|
void g_static_private_set (GStaticPrivate *private_key,
|
||||||
GDestroyNotify notify);
|
gpointer data,
|
||||||
gpointer g_static_private_get_for_thread (GStaticPrivate *private_key,
|
GDestroyNotify notify);
|
||||||
GThread *thread);
|
gpointer g_static_private_get_for_thread (GStaticPrivate *private_key,
|
||||||
void g_static_private_set_for_thread (GStaticPrivate *private_key,
|
GThread *thread);
|
||||||
GThread *thread,
|
void g_static_private_set_for_thread (GStaticPrivate *private_key,
|
||||||
gpointer data,
|
GThread *thread,
|
||||||
GDestroyNotify notify);
|
gpointer data,
|
||||||
|
GDestroyNotify notify);
|
||||||
|
void g_static_private_free (GStaticPrivate *private_key);
|
||||||
|
|
||||||
typedef struct _GStaticRecMutex GStaticRecMutex;
|
typedef struct _GStaticRecMutex GStaticRecMutex;
|
||||||
struct _GStaticRecMutex
|
struct _GStaticRecMutex
|
||||||
@ -255,12 +257,14 @@ struct _GStaticRecMutex
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define G_STATIC_REC_MUTEX_INIT { G_STATIC_MUTEX_INIT }
|
#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);
|
void g_static_rec_mutex_lock (GStaticRecMutex *mutex);
|
||||||
gboolean g_static_rec_mutex_trylock (GStaticRecMutex *mutex);
|
gboolean g_static_rec_mutex_trylock (GStaticRecMutex *mutex);
|
||||||
void g_static_rec_mutex_unlock (GStaticRecMutex *mutex);
|
void g_static_rec_mutex_unlock (GStaticRecMutex *mutex);
|
||||||
void g_static_rec_mutex_lock_full (GStaticRecMutex *mutex,
|
void g_static_rec_mutex_lock_full (GStaticRecMutex *mutex,
|
||||||
guint depth);
|
guint depth);
|
||||||
guint g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex);
|
guint g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex);
|
||||||
|
void g_static_rec_mutex_free (GStaticRecMutex *mutex);
|
||||||
|
|
||||||
typedef struct _GStaticRWLock GStaticRWLock;
|
typedef struct _GStaticRWLock GStaticRWLock;
|
||||||
struct _GStaticRWLock
|
struct _GStaticRWLock
|
||||||
@ -275,13 +279,14 @@ struct _GStaticRWLock
|
|||||||
|
|
||||||
#define G_STATIC_RW_LOCK_INIT { G_STATIC_MUTEX_INIT, NULL, NULL, 0, FALSE, FALSE }
|
#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);
|
void g_static_rw_lock_reader_lock (GStaticRWLock* lock);
|
||||||
gboolean g_static_rw_lock_reader_trylock (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_reader_unlock (GStaticRWLock* lock);
|
||||||
void g_static_rw_lock_writer_lock (GStaticRWLock* lock);
|
void g_static_rw_lock_writer_lock (GStaticRWLock* lock);
|
||||||
gboolean g_static_rw_lock_writer_trylock (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_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
|
/* these are some convenience macros that expand to nothing if GLib
|
||||||
* was configured with --disable-threads. for using StaticMutexes,
|
* was configured with --disable-threads. for using StaticMutexes,
|
||||||
|
@ -81,9 +81,11 @@ test_g_static_rec_mutex (void)
|
|||||||
|
|
||||||
#define THREADS 10
|
#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 GStaticMutex test_g_static_private_mutex = G_STATIC_MUTEX_INIT;
|
||||||
static guint test_g_static_private_counter = 0;
|
static guint test_g_static_private_counter = 0;
|
||||||
|
static guint test_g_static_private_ready = 0;
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
test_g_static_private_constructor (void)
|
test_g_static_private_constructor (void)
|
||||||
@ -109,20 +111,51 @@ test_g_static_private_thread (gpointer data)
|
|||||||
{
|
{
|
||||||
guint number = GPOINTER_TO_INT (data);
|
guint number = GPOINTER_TO_INT (data);
|
||||||
guint i;
|
guint i;
|
||||||
guint* private;
|
guint *private1, *private2;
|
||||||
for (i = 0; i < 10; i++)
|
for (i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
number = number * 11 + 1; /* A very simple and bad RNG ;-) */
|
number = number * 11 + 1; /* A very simple and bad RNG ;-) */
|
||||||
private = g_static_private_get (&test_g_static_private_private);
|
private1 = g_static_private_get (&test_g_static_private_private1);
|
||||||
if (!private || number % 7 > 3)
|
if (!private1 || number % 7 > 3)
|
||||||
{
|
{
|
||||||
private = test_g_static_private_constructor ();
|
private1 = test_g_static_private_constructor ();
|
||||||
g_static_private_set (&test_g_static_private_private, private,
|
g_static_private_set (&test_g_static_private_private1, private1,
|
||||||
test_g_static_private_destructor);
|
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_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];
|
GThread *threads[THREADS];
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
|
test_g_static_private_ready = 0;
|
||||||
|
|
||||||
for (i = 0; i < THREADS; i++)
|
for (i = 0; i < THREADS; i++)
|
||||||
{
|
{
|
||||||
threads[i] = g_thread_create (test_g_static_private_thread,
|
threads[i] = g_thread_create (test_g_static_private_thread,
|
||||||
@ -138,6 +174,17 @@ test_g_static_private (void)
|
|||||||
0, TRUE, TRUE,
|
0, TRUE, TRUE,
|
||||||
G_THREAD_PRIORITY_NORMAL, NULL);
|
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++)
|
for (i = 0; i < THREADS; i++)
|
||||||
{
|
{
|
||||||
g_thread_join (threads[i]);
|
g_thread_join (threads[i]);
|
||||||
@ -231,7 +278,7 @@ run_all_tests()
|
|||||||
test_g_mutex ();
|
test_g_mutex ();
|
||||||
test_g_static_rec_mutex ();
|
test_g_static_rec_mutex ();
|
||||||
test_g_static_private ();
|
test_g_static_private ();
|
||||||
test_g_static_rw_lock ();
|
test_g_static_rw_lock ();
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
Loading…
x
Reference in New Issue
Block a user