mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-26 22:16:16 +01:00
Merge branch '1224-tsan-fixes' into 'master'
Patches to improve GObject and GThread with TSAN Closes #1224 See merge request GNOME/glib!383
This commit is contained in:
commit
5360fd0666
@ -1148,15 +1148,26 @@ g_system_thread_free (GRealThread *thread)
|
||||
}
|
||||
|
||||
GRealThread *
|
||||
g_system_thread_new (GThreadFunc thread_func,
|
||||
g_system_thread_new (GThreadFunc proxy,
|
||||
gulong stack_size,
|
||||
const char *name,
|
||||
GThreadFunc func,
|
||||
gpointer data,
|
||||
GError **error)
|
||||
{
|
||||
GThreadPosix *thread;
|
||||
GRealThread *base_thread;
|
||||
pthread_attr_t attr;
|
||||
gint ret;
|
||||
|
||||
thread = g_slice_new0 (GThreadPosix);
|
||||
base_thread = (GRealThread*)thread;
|
||||
base_thread->ref_count = 2;
|
||||
base_thread->ours = TRUE;
|
||||
base_thread->thread.joinable = TRUE;
|
||||
base_thread->thread.func = func;
|
||||
base_thread->thread.data = data;
|
||||
base_thread->name = g_strdup (name);
|
||||
|
||||
posix_check_cmd (pthread_attr_init (&attr));
|
||||
|
||||
@ -1174,7 +1185,7 @@ g_system_thread_new (GThreadFunc thread_func,
|
||||
}
|
||||
#endif /* HAVE_PTHREAD_ATTR_SETSTACKSIZE */
|
||||
|
||||
ret = pthread_create (&thread->system_thread, &attr, (void* (*)(void*))thread_func, thread);
|
||||
ret = pthread_create (&thread->system_thread, &attr, (void* (*)(void*))proxy, thread);
|
||||
|
||||
posix_check_cmd (pthread_attr_destroy (&attr));
|
||||
|
||||
|
@ -429,15 +429,26 @@ g_thread_win32_proxy (gpointer data)
|
||||
}
|
||||
|
||||
GRealThread *
|
||||
g_system_thread_new (GThreadFunc func,
|
||||
g_system_thread_new (GThreadFunc proxy,
|
||||
gulong stack_size,
|
||||
const char *name,
|
||||
GThreadFunc func,
|
||||
gpointer data,
|
||||
GError **error)
|
||||
{
|
||||
GThreadWin32 *thread;
|
||||
GRealThread *base_thread;
|
||||
guint ignore;
|
||||
|
||||
thread = g_slice_new0 (GThreadWin32);
|
||||
thread->proxy = func;
|
||||
thread->proxy = proxy;
|
||||
base_thread = (GRealThread*)thread;
|
||||
base_thread->ref_count = 2;
|
||||
base_thread->ours = TRUE;
|
||||
base_thread->thread.joinable = TRUE;
|
||||
base_thread->thread.func = func;
|
||||
base_thread->thread.data = data;
|
||||
base_thread->name = g_strdup (name);
|
||||
|
||||
thread->handle = (HANDLE) _beginthreadex (NULL, stack_size, g_thread_win32_proxy, thread, 0, &ignore);
|
||||
|
||||
|
@ -515,8 +515,6 @@ static GSList *g_once_init_list = NULL;
|
||||
static void g_thread_cleanup (gpointer data);
|
||||
static GPrivate g_thread_specific_private = G_PRIVATE_INIT (g_thread_cleanup);
|
||||
|
||||
G_LOCK_DEFINE_STATIC (g_thread_new);
|
||||
|
||||
/*
|
||||
* g_private_set_alloc0:
|
||||
* @key: a #GPrivate
|
||||
@ -792,16 +790,8 @@ g_thread_proxy (gpointer data)
|
||||
GRealThread* thread = data;
|
||||
|
||||
g_assert (data);
|
||||
|
||||
/* This has to happen before G_LOCK, as that might call g_thread_self */
|
||||
g_private_set (&g_thread_specific_private, data);
|
||||
|
||||
/* The lock makes sure that g_thread_new_internal() has a chance to
|
||||
* setup 'func' and 'data' before we make the call.
|
||||
*/
|
||||
G_LOCK (g_thread_new);
|
||||
G_UNLOCK (g_thread_new);
|
||||
|
||||
TRACE (GLIB_THREAD_SPAWNED (thread->thread.func, thread->thread.data,
|
||||
thread->name));
|
||||
|
||||
@ -897,24 +887,10 @@ g_thread_new_internal (const gchar *name,
|
||||
gsize stack_size,
|
||||
GError **error)
|
||||
{
|
||||
GRealThread *thread;
|
||||
|
||||
g_return_val_if_fail (func != NULL, NULL);
|
||||
|
||||
G_LOCK (g_thread_new);
|
||||
thread = g_system_thread_new (proxy, stack_size, error);
|
||||
if (thread)
|
||||
{
|
||||
thread->ref_count = 2;
|
||||
thread->ours = TRUE;
|
||||
thread->thread.joinable = TRUE;
|
||||
thread->thread.func = func;
|
||||
thread->thread.data = data;
|
||||
thread->name = g_strdup (name);
|
||||
}
|
||||
G_UNLOCK (g_thread_new);
|
||||
|
||||
return (GThread*) thread;
|
||||
return (GThread*) g_system_thread_new (proxy, stack_size, name,
|
||||
func, data, error);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -37,8 +37,11 @@ struct _GRealThread
|
||||
/* system thread implementation (gthread-posix.c, gthread-win32.c) */
|
||||
void g_system_thread_wait (GRealThread *thread);
|
||||
|
||||
GRealThread * g_system_thread_new (GThreadFunc func,
|
||||
GRealThread * g_system_thread_new (GThreadFunc proxy,
|
||||
gulong stack_size,
|
||||
const char *name,
|
||||
GThreadFunc func,
|
||||
gpointer data,
|
||||
GError **error);
|
||||
void g_system_thread_free (GRealThread *thread);
|
||||
|
||||
|
@ -3210,9 +3210,9 @@ gpointer
|
||||
gint old_val;
|
||||
|
||||
g_return_val_if_fail (G_IS_OBJECT (object), NULL);
|
||||
g_return_val_if_fail (object->ref_count > 0, NULL);
|
||||
|
||||
old_val = g_atomic_int_add (&object->ref_count, 1);
|
||||
g_return_val_if_fail (old_val > 0, NULL);
|
||||
|
||||
if (old_val == 1 && OBJECT_HAS_TOGGLE_REF (object))
|
||||
toggle_refs_notify (object, FALSE);
|
||||
@ -3241,7 +3241,6 @@ g_object_unref (gpointer _object)
|
||||
gint old_ref;
|
||||
|
||||
g_return_if_fail (G_IS_OBJECT (object));
|
||||
g_return_if_fail (object->ref_count > 0);
|
||||
|
||||
/* here we want to atomically do: if (ref_count>1) { ref_count--; return; } */
|
||||
retry_atomic_decrement1:
|
||||
@ -3336,6 +3335,7 @@ g_object_unref (gpointer _object)
|
||||
|
||||
/* decrement the last reference */
|
||||
old_ref = g_atomic_int_add (&object->ref_count, -1);
|
||||
g_return_if_fail (old_ref > 0);
|
||||
|
||||
TRACE (GOBJECT_OBJECT_UNREF(object,G_TYPE_FROM_INSTANCE(object),old_ref));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user