mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-10-24 14:02:18 +02:00
Stop dithering over GPrivate
Take out the half-private g_private_init() stuff and replace it with a G_PRIVATE_INIT macro that allows specifying a GDestroyNotify. Expose the GPrivate structure in a public header. Add a g_private_replace() to (sort of) match the functionality of g_static_mutex_set(). Improve the documentation. Deprecate g_private_new().
This commit is contained in:
100
glib/gthread.c
100
glib/gthread.c
@@ -523,58 +523,6 @@
|
||||
* Since: 2.32
|
||||
*/
|
||||
|
||||
/* GPrivate Documentation {{{1 --------------------------------------- */
|
||||
|
||||
/**
|
||||
* GPrivate:
|
||||
*
|
||||
* <note><para>
|
||||
* #GStaticPrivate is a better choice for most uses.
|
||||
* </para></note>
|
||||
*
|
||||
* The #GPrivate struct is an opaque data structure to represent a
|
||||
* thread private data key. Threads can thereby obtain and set a
|
||||
* pointer which is private to the current thread. Take our
|
||||
* <function>give_me_next_number(<!-- -->)</function> example from
|
||||
* above. Suppose we don't want <literal>current_number</literal> to be
|
||||
* shared between the threads, but instead to be private to each thread.
|
||||
* This can be done as follows:
|
||||
*
|
||||
* <example>
|
||||
* <title>Using GPrivate for per-thread data</title>
|
||||
* <programlisting>
|
||||
* GPrivate* current_number_key = NULL; /<!-- -->* Must be initialized somewhere
|
||||
* with g_private_new (g_free); *<!-- -->/
|
||||
*
|
||||
* int
|
||||
* give_me_next_number (void)
|
||||
* {
|
||||
* int *current_number = g_private_get (current_number_key);
|
||||
*
|
||||
* if (!current_number)
|
||||
* {
|
||||
* current_number = g_new (int, 1);
|
||||
* *current_number = 0;
|
||||
* g_private_set (current_number_key, current_number);
|
||||
* }
|
||||
*
|
||||
* *current_number = calc_next_number (*current_number);
|
||||
*
|
||||
* return *current_number;
|
||||
* }
|
||||
* </programlisting>
|
||||
* </example>
|
||||
*
|
||||
* Here the pointer belonging to the key
|
||||
* <literal>current_number_key</literal> is read. If it is %NULL, it has
|
||||
* not been set yet. Then get memory for an integer value, assign this
|
||||
* memory to the pointer and write the pointer back. Now we have an
|
||||
* integer value that is private to the current thread.
|
||||
*
|
||||
* The #GPrivate struct should only be accessed via the
|
||||
* <function>g_private_</function> functions.
|
||||
*/
|
||||
|
||||
/* GThread Documentation {{{1 ---------------------------------------- */
|
||||
|
||||
/**
|
||||
@@ -649,7 +597,8 @@ GMutex g_once_mutex = G_MUTEX_INIT;
|
||||
static GCond g_once_cond = G_COND_INIT;
|
||||
static GSList *g_once_init_list = NULL;
|
||||
|
||||
static GPrivate g_thread_specific_private;
|
||||
static void g_thread_cleanup (gpointer data);
|
||||
static GPrivate g_thread_specific_private = G_PRIVATE_INIT (g_thread_cleanup);
|
||||
static GRealThread *g_thread_all_threads = NULL;
|
||||
static GSList *g_thread_free_indices = NULL;
|
||||
|
||||
@@ -684,8 +633,6 @@ G_LOCK_DEFINE_STATIC (g_thread);
|
||||
* having to link with the thread libraries.</para></note>
|
||||
*/
|
||||
|
||||
static void g_thread_cleanup (gpointer data);
|
||||
|
||||
void
|
||||
g_thread_init_glib (void)
|
||||
{
|
||||
@@ -704,7 +651,6 @@ g_thread_init_glib (void)
|
||||
|
||||
/* setup the basic threading system */
|
||||
g_threads_got_initialized = TRUE;
|
||||
g_private_init (&g_thread_specific_private, g_thread_cleanup);
|
||||
g_private_set (&g_thread_specific_private, main_thread);
|
||||
g_system_thread_self (&main_thread->system_thread);
|
||||
|
||||
@@ -1537,43 +1483,5 @@ g_cond_free (GCond *cond)
|
||||
g_slice_free (GCond, cond);
|
||||
}
|
||||
|
||||
/* GPrivate {{{1 ------------------------------------------------------ */
|
||||
|
||||
/**
|
||||
* g_private_new:
|
||||
* @destructor: a function to destroy the data keyed to
|
||||
* the #GPrivate when a thread ends
|
||||
*
|
||||
* Creates a new #GPrivate. If @destructor is non-%NULL, it is a
|
||||
* pointer to a destructor function. Whenever a thread ends and the
|
||||
* corresponding pointer keyed to this instance of #GPrivate is
|
||||
* non-%NULL, the destructor is called with this pointer as the
|
||||
* argument.
|
||||
*
|
||||
* <note><para>
|
||||
* #GStaticPrivate is a better choice for most uses.
|
||||
* </para></note>
|
||||
*
|
||||
* <note><para>@destructor is used quite differently from @notify in
|
||||
* g_static_private_set().</para></note>
|
||||
*
|
||||
* <note><para>A #GPrivate cannot be freed. Reuse it instead, if you
|
||||
* can, to avoid shortage, or use #GStaticPrivate.</para></note>
|
||||
*
|
||||
* <note><para>This function will abort if g_thread_init() has not been
|
||||
* called yet.</para></note>
|
||||
*
|
||||
* Returns: a newly allocated #GPrivate
|
||||
*/
|
||||
GPrivate *
|
||||
g_private_new (GDestroyNotify notify)
|
||||
{
|
||||
GPrivate *key;
|
||||
|
||||
key = g_slice_new (GPrivate);
|
||||
g_private_init (key, notify);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
/* vim: set foldmethod=marker: */
|
||||
/* Epilogue {{{1 */
|
||||
/* vim: set foldmethod=marker: */
|
||||
|
||||
Reference in New Issue
Block a user