[glib] GStaticPrivate: protect GRealThread.private_data with a bit-lock
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] GStaticPrivate: protect GRealThread.private_data with a bit-lock
- Date: Sat, 28 May 2011 18:00:12 +0000 (UTC)
commit e83210425fb407e6fa7be2dcc7ac53d4d30e9a7c
Author: Simon McVittie <simon mcvittie collabora co uk>
Date: Tue May 24 16:23:38 2011 +0100
GStaticPrivate: protect GRealThread.private_data with a bit-lock
Bug: https://bugzilla.gnome.org/show_bug.cgi?id=642026
Bug-NB: NB#257512
glib/gthread.c | 23 +++++++++++++++++++++--
1 files changed, 21 insertions(+), 2 deletions(-)
---
diff --git a/glib/gthread.c b/glib/gthread.c
index 1b82f99..8302011 100644
--- a/glib/gthread.c
+++ b/glib/gthread.c
@@ -57,11 +57,11 @@
#include <string.h>
#include "garray.h"
+#include "gbitlock.h"
#include "gslist.h"
#include "gtestutils.h"
#include "gtimer.h"
-
/**
* SECTION:threads
* @title: Threads
@@ -262,12 +262,18 @@ typedef struct _GRealThread GRealThread;
struct _GRealThread
{
GThread thread;
- gpointer private_data;
+ /* Bit 0 protects private_data. To avoid deadlocks, do not block while
+ * holding this (particularly on the g_thread lock). */
+ volatile gint private_data_lock;
+ GArray *private_data;
GRealThread *next;
gpointer retval;
GSystemThread system_thread;
};
+#define LOCK_PRIVATE_DATA(self) g_bit_lock (&(self)->private_data_lock, 0)
+#define UNLOCK_PRIVATE_DATA(self) g_bit_unlock (&(self)->private_data_lock, 0)
+
typedef struct _GStaticPrivateNode GStaticPrivateNode;
struct _GStaticPrivateNode
{
@@ -1655,12 +1661,15 @@ g_static_private_get (GStaticPrivate *private_key)
GArray *array;
gpointer ret = NULL;
+ LOCK_PRIVATE_DATA (self);
+
array = self->private_data;
if (array && private_key->index != 0 && private_key->index <= array->len)
ret = g_array_index (array, GStaticPrivateNode,
private_key->index - 1).data;
+ UNLOCK_PRIVATE_DATA (self);
return ret;
}
@@ -1717,6 +1726,8 @@ g_static_private_set (GStaticPrivate *private_key,
G_UNLOCK (g_thread);
}
+ LOCK_PRIVATE_DATA (self);
+
array = self->private_data;
if (!array)
{
@@ -1735,6 +1746,8 @@ g_static_private_set (GStaticPrivate *private_key,
node->data = data;
node->destroy = notify;
+ UNLOCK_PRIVATE_DATA (self);
+
if (ddestroy)
ddestroy (ddata);
}
@@ -1772,6 +1785,8 @@ g_static_private_free (GStaticPrivate *private_key)
next = thread->next;
+ LOCK_PRIVATE_DATA (thread);
+
array = thread->private_data;
if (array && idx <= array->len)
@@ -1801,6 +1816,8 @@ g_static_private_free (GStaticPrivate *private_key)
node->destroy = ddestroy;
}
}
+
+ UNLOCK_PRIVATE_DATA (thread);
}
g_thread_free_indeces = g_slist_prepend (g_thread_free_indeces,
GUINT_TO_POINTER (idx));
@@ -1831,8 +1848,10 @@ g_thread_cleanup (gpointer data)
GRealThread* thread = data;
GArray *array;
+ LOCK_PRIVATE_DATA (thread);
array = thread->private_data;
thread->private_data = NULL;
+ UNLOCK_PRIVATE_DATA (thread);
if (array)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]