mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-27 07:56:14 +01:00
GStaticPrivate: protect GRealThread.private_data with a bit-lock
Bug: https://bugzilla.gnome.org/show_bug.cgi?id=642026 Bug-NB: NB#257512
This commit is contained in:
parent
83f1b12388
commit
e83210425f
@ -57,11 +57,11 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "garray.h"
|
#include "garray.h"
|
||||||
|
#include "gbitlock.h"
|
||||||
#include "gslist.h"
|
#include "gslist.h"
|
||||||
#include "gtestutils.h"
|
#include "gtestutils.h"
|
||||||
#include "gtimer.h"
|
#include "gtimer.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:threads
|
* SECTION:threads
|
||||||
* @title: Threads
|
* @title: Threads
|
||||||
@ -262,12 +262,18 @@ typedef struct _GRealThread GRealThread;
|
|||||||
struct _GRealThread
|
struct _GRealThread
|
||||||
{
|
{
|
||||||
GThread thread;
|
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;
|
GRealThread *next;
|
||||||
gpointer retval;
|
gpointer retval;
|
||||||
GSystemThread system_thread;
|
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;
|
typedef struct _GStaticPrivateNode GStaticPrivateNode;
|
||||||
struct _GStaticPrivateNode
|
struct _GStaticPrivateNode
|
||||||
{
|
{
|
||||||
@ -1655,12 +1661,15 @@ g_static_private_get (GStaticPrivate *private_key)
|
|||||||
GArray *array;
|
GArray *array;
|
||||||
gpointer ret = NULL;
|
gpointer ret = NULL;
|
||||||
|
|
||||||
|
LOCK_PRIVATE_DATA (self);
|
||||||
|
|
||||||
array = self->private_data;
|
array = self->private_data;
|
||||||
|
|
||||||
if (array && private_key->index != 0 && private_key->index <= array->len)
|
if (array && private_key->index != 0 && private_key->index <= array->len)
|
||||||
ret = g_array_index (array, GStaticPrivateNode,
|
ret = g_array_index (array, GStaticPrivateNode,
|
||||||
private_key->index - 1).data;
|
private_key->index - 1).data;
|
||||||
|
|
||||||
|
UNLOCK_PRIVATE_DATA (self);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1717,6 +1726,8 @@ g_static_private_set (GStaticPrivate *private_key,
|
|||||||
G_UNLOCK (g_thread);
|
G_UNLOCK (g_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOCK_PRIVATE_DATA (self);
|
||||||
|
|
||||||
array = self->private_data;
|
array = self->private_data;
|
||||||
if (!array)
|
if (!array)
|
||||||
{
|
{
|
||||||
@ -1735,6 +1746,8 @@ g_static_private_set (GStaticPrivate *private_key,
|
|||||||
node->data = data;
|
node->data = data;
|
||||||
node->destroy = notify;
|
node->destroy = notify;
|
||||||
|
|
||||||
|
UNLOCK_PRIVATE_DATA (self);
|
||||||
|
|
||||||
if (ddestroy)
|
if (ddestroy)
|
||||||
ddestroy (ddata);
|
ddestroy (ddata);
|
||||||
}
|
}
|
||||||
@ -1772,6 +1785,8 @@ g_static_private_free (GStaticPrivate *private_key)
|
|||||||
|
|
||||||
next = thread->next;
|
next = thread->next;
|
||||||
|
|
||||||
|
LOCK_PRIVATE_DATA (thread);
|
||||||
|
|
||||||
array = thread->private_data;
|
array = thread->private_data;
|
||||||
|
|
||||||
if (array && idx <= array->len)
|
if (array && idx <= array->len)
|
||||||
@ -1801,6 +1816,8 @@ g_static_private_free (GStaticPrivate *private_key)
|
|||||||
node->destroy = ddestroy;
|
node->destroy = ddestroy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UNLOCK_PRIVATE_DATA (thread);
|
||||||
}
|
}
|
||||||
g_thread_free_indeces = g_slist_prepend (g_thread_free_indeces,
|
g_thread_free_indeces = g_slist_prepend (g_thread_free_indeces,
|
||||||
GUINT_TO_POINTER (idx));
|
GUINT_TO_POINTER (idx));
|
||||||
@ -1831,8 +1848,10 @@ g_thread_cleanup (gpointer data)
|
|||||||
GRealThread* thread = data;
|
GRealThread* thread = data;
|
||||||
GArray *array;
|
GArray *array;
|
||||||
|
|
||||||
|
LOCK_PRIVATE_DATA (thread);
|
||||||
array = thread->private_data;
|
array = thread->private_data;
|
||||||
thread->private_data = NULL;
|
thread->private_data = NULL;
|
||||||
|
UNLOCK_PRIVATE_DATA (thread);
|
||||||
|
|
||||||
if (array)
|
if (array)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user