/* Initialisation {{{1 ---------------------------------------------------- */
gboolean g_threads_got_initialized = TRUE;
-GSystemThread zero_thread; /* This is initialized to all zero */
-
/**
* g_thread_init:
/* Internal variables {{{1 */
-static GRealThread *g_thread_all_threads = NULL;
+static GSList *g_thread_all_threads = NULL;
static GSList *g_thread_free_indices = NULL;
/* Protects g_thread_all_threads and g_thread_free_indices */
+G_LOCK_DEFINE_STATIC (g_static_mutex);
G_LOCK_DEFINE_STATIC (g_thread);
/* Misc. GThread functions {{{1 */
g_return_if_fail (thread_func != NULL);
/* snapshot the list of threads for iteration */
G_LOCK (g_thread);
- for (thread = g_thread_all_threads; thread; thread = thread->next)
- slist = g_slist_prepend (slist, thread);
+ slist = g_slist_copy (g_thread_all_threads);
G_UNLOCK (g_thread);
/* walk the list, skipping non-existent threads */
while (slist)
slist = node->next;
/* check whether the current thread still exists */
G_LOCK (g_thread);
- for (thread = g_thread_all_threads; thread; thread = thread->next)
- if (thread == node->data)
- break;
+ if (g_slist_find (g_thread_all_threads, node->data))
+ thread = node->data;
+ else
+ thread = NULL;
G_UNLOCK (g_thread);
if (thread)
thread_func (thread, user_data);
g_enumerable_thread_remove (gpointer data)
{
GRealThread *thread = data;
- GRealThread *t, *p;
G_LOCK (g_thread);
- for (t = g_thread_all_threads, p = NULL; t; p = t, t = t->next)
- {
- if (t == thread)
- {
- if (p)
- p->next = t->next;
- else
- g_thread_all_threads = t->next;
- break;
- }
- }
+ g_thread_all_threads = g_slist_remove (g_thread_all_threads, thread);
G_UNLOCK (g_thread);
}
g_enumerable_thread_add (GRealThread *thread)
{
G_LOCK (g_thread);
- thread->next = g_thread_all_threads;
- g_thread_all_threads = thread;
+ g_thread_all_threads = g_slist_prepend (g_thread_all_threads, thread);
G_UNLOCK (g_thread);
g_private_set (&enumerable_thread_private, thread);
}
+
+static gpointer
+g_deprecated_thread_proxy (gpointer data)
+{
+ GRealThread *real = data;
+
+ g_enumerable_thread_add (real);
+
+ return g_thread_proxy (data);
+}
+
/**
* g_thread_create:
* @func: a function to execute in the new thread
*
* This function creates a new thread.
*
- * If @joinable is %TRUE, you can wait for this threads termination
- * calling g_thread_join(). Otherwise the thread will just disappear
- * when it terminates.
- *
* The new thread executes the function @func with the argument @data.
* If the thread was created successfully, it is returned.
*
* @error can be %NULL to ignore errors, or non-%NULL to report errors.
* The error is set, if and only if the function returns %NULL.
*
+ * This function returns a reference to the created thread only if
+ * @joinable is %TRUE. In that case, you must free this reference by
+ * calling g_thread_unref() or g_thread_join(). If @joinable is %FALSE
+ * then you should probably not touch the return value.
+ *
* Returns: the new #GThread on success
*
* Deprecated:2.32: Use g_thread_new() instead
gboolean joinable,
GError **error)
{
- return g_thread_new_internal (NULL, func, data, joinable, 0, g_enumerable_thread_add, error);
+ return g_thread_create_full (func, data, 0, joinable, 0, 0, error);
}
/**
* This function creates a new thread.
*
* Deprecated:2.32: The @bound and @priority arguments are now ignored.
- * Use g_thread_new() or g_thread_new_full() instead.
+ * Use g_thread_new().
*/
GThread *
g_thread_create_full (GThreadFunc func,
GThreadPriority priority,
GError **error)
{
- return g_thread_new_internal (NULL, func, data, joinable, stack_size, g_enumerable_thread_add, error);
-}
+ GThread *thread;
+ thread = g_thread_new_internal (NULL, g_deprecated_thread_proxy,
+ func, data, stack_size, error);
+ if (!joinable)
+ {
+ thread->joinable = FALSE;
+ g_thread_unref (thread);
+ }
+
+ return thread;
+}
/* GOnce {{{1 ------------------------------------------------------------- */
gboolean
if (!result)
{
- g_mutex_lock (&g_once_mutex);
+ G_LOCK (g_static_mutex);
result = mutex->mutex;
if (!result)
g_atomic_pointer_set (&mutex->mutex, result);
}
- g_mutex_unlock (&g_once_mutex);
+ G_UNLOCK (g_static_mutex);
}
return result;
*mutex = init_mutex;
}
+static GRecMutex *
+g_static_rec_mutex_get_rec_mutex_impl (GStaticRecMutex* mutex)
+{
+ GRecMutex *result;
+
+ if (!g_thread_supported ())
+ return NULL;
+
+ result = g_atomic_pointer_get (&mutex->mutex.mutex);
+
+ if (!result)
+ {
+ G_LOCK (g_static_mutex);
+
+ result = (GRecMutex *) mutex->mutex.mutex;
+ if (!result)
+ {
+ result = g_slice_new (GRecMutex);
+ g_rec_mutex_init (result);
+ g_atomic_pointer_set (&mutex->mutex.mutex, result);
+ }
+
+ G_UNLOCK (g_static_mutex);
+ }
+
+ return result;
+}
+
/**
* g_static_rec_mutex_lock:
* @mutex: a #GStaticRecMutex to lock.
void
g_static_rec_mutex_lock (GStaticRecMutex* mutex)
{
- GSystemThread self;
-
- g_return_if_fail (mutex);
-
- if (!g_thread_supported ())
- return;
-
- g_system_thread_self (&self);
-
- if (g_system_thread_equal (&self, &mutex->owner))
- {
- mutex->depth++;
- return;
- }
- g_static_mutex_lock (&mutex->mutex);
- g_system_thread_assign (mutex->owner, self);
- mutex->depth = 1;
+ GRecMutex *rm;
+ rm = g_static_rec_mutex_get_rec_mutex_impl (mutex);
+ g_rec_mutex_lock (rm);
+ mutex->depth++;
}
/**
gboolean
g_static_rec_mutex_trylock (GStaticRecMutex* mutex)
{
- GSystemThread self;
-
- g_return_val_if_fail (mutex, FALSE);
+ GRecMutex *rm;
+ rm = g_static_rec_mutex_get_rec_mutex_impl (mutex);
- if (!g_thread_supported ())
- return TRUE;
-
- g_system_thread_self (&self);
-
- if (g_system_thread_equal (&self, &mutex->owner))
+ if (g_rec_mutex_trylock (rm))
{
mutex->depth++;
return TRUE;
}
-
- if (!g_static_mutex_trylock (&mutex->mutex))
+ else
return FALSE;
-
- g_system_thread_assign (mutex->owner, self);
- mutex->depth = 1;
- return TRUE;
}
/**
void
g_static_rec_mutex_unlock (GStaticRecMutex* mutex)
{
- g_return_if_fail (mutex);
-
- if (!g_thread_supported ())
- return;
-
- if (mutex->depth > 1)
- {
- mutex->depth--;
- return;
- }
- g_system_thread_assign (mutex->owner, zero_thread);
- g_static_mutex_unlock (&mutex->mutex);
+ GRecMutex *rm;
+ rm = g_static_rec_mutex_get_rec_mutex_impl (mutex);
+ mutex->depth--;
+ g_rec_mutex_unlock (rm);
}
/**
g_static_rec_mutex_lock_full (GStaticRecMutex *mutex,
guint depth)
{
- GSystemThread self;
- g_return_if_fail (mutex);
-
- if (!g_thread_supported ())
- return;
-
- if (depth == 0)
- return;
+ GRecMutex *rm;
- g_system_thread_self (&self);
-
- if (g_system_thread_equal (&self, &mutex->owner))
+ rm = g_static_rec_mutex_get_rec_mutex_impl (mutex);
+ while (depth--)
{
- mutex->depth += depth;
- return;
+ g_rec_mutex_lock (rm);
+ mutex->depth++;
}
- g_static_mutex_lock (&mutex->mutex);
- g_system_thread_assign (mutex->owner, self);
- mutex->depth = depth;
}
/**
guint
g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex)
{
- guint depth;
-
- g_return_val_if_fail (mutex, 0);
-
- if (!g_thread_supported ())
- return 1;
+ GRecMutex *rm;
+ gint depth;
+ rm = g_static_rec_mutex_get_rec_mutex_impl (mutex);
depth = mutex->depth;
-
- g_system_thread_assign (mutex->owner, zero_thread);
- mutex->depth = 0;
- g_static_mutex_unlock (&mutex->mutex);
+ while (mutex->depth--)
+ g_rec_mutex_unlock (rm);
return depth;
}
{
g_return_if_fail (mutex);
- g_static_mutex_free (&mutex->mutex);
+ if (mutex->mutex.mutex)
+ {
+ GRecMutex *rm = (GRecMutex *) mutex->mutex.mutex;
+
+ g_rec_mutex_clear (rm);
+ g_slice_free (GRecMutex, rm);
+ }
}
/* GStaticRWLock {{{1 ----------------------------------------------------- */