gmain: use Linux eventfd() for main context wake up
[glib.git] / glib / gdataset.c
blobb58d66c0f2354b13180babbf3ab6b990854a0a1a
1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * gdataset.c: Generic dataset mechanism, similar to GtkObject data.
5 * Copyright (C) 1998 Tim Janik
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
23 * Modified by the GLib Team and others 1997-2000. See the AUTHORS
24 * file for a list of people on the GLib Team. See the ChangeLog
25 * files for a list of changes. These files are distributed with
26 * GLib at ftp://ftp.gtk.org/pub/gtk/.
30 * MT safe ; except for g_data*_foreach()
33 #include "config.h"
35 #include <string.h>
37 #include "gdataset.h"
38 #include "gbitlock.h"
40 #include "gdatasetprivate.h"
41 #include "ghash.h"
42 #include "gquark.h"
43 #include "gstrfuncs.h"
44 #include "gtestutils.h"
45 #include "gthread.h"
46 #include "glib_trace.h"
48 /**
49 * SECTION:datasets
50 * @title: Datasets
51 * @short_description: associate groups of data elements with
52 * particular memory locations
54 * Datasets associate groups of data elements with particular memory
55 * locations. These are useful if you need to associate data with a
56 * structure returned from an external library. Since you cannot modify
57 * the structure, you use its location in memory as the key into a
58 * dataset, where you can associate any number of data elements with it.
60 * There are two forms of most of the dataset functions. The first form
61 * uses strings to identify the data elements associated with a
62 * location. The second form uses #GQuark identifiers, which are
63 * created with a call to g_quark_from_string() or
64 * g_quark_from_static_string(). The second form is quicker, since it
65 * does not require looking up the string in the hash table of #GQuark
66 * identifiers.
68 * There is no function to create a dataset. It is automatically
69 * created as soon as you add elements to it.
71 * To add data elements to a dataset use g_dataset_id_set_data(),
72 * g_dataset_id_set_data_full(), g_dataset_set_data() and
73 * g_dataset_set_data_full().
75 * To get data elements from a dataset use g_dataset_id_get_data() and
76 * g_dataset_get_data().
78 * To iterate over all data elements in a dataset use
79 * g_dataset_foreach() (not thread-safe).
81 * To remove data elements from a dataset use
82 * g_dataset_id_remove_data() and g_dataset_remove_data().
84 * To destroy a dataset, use g_dataset_destroy().
85 **/
87 /**
88 * SECTION:datalist
89 * @title: Keyed Data Lists
90 * @short_description: lists of data elements which are accessible by a
91 * string or GQuark identifier
93 * Keyed data lists provide lists of arbitrary data elements which can
94 * be accessed either with a string or with a #GQuark corresponding to
95 * the string.
97 * The #GQuark methods are quicker, since the strings have to be
98 * converted to #GQuarks anyway.
100 * Data lists are used for associating arbitrary data with #GObjects,
101 * using g_object_set_data() and related functions.
103 * To create a datalist, use g_datalist_init().
105 * To add data elements to a datalist use g_datalist_id_set_data(),
106 * g_datalist_id_set_data_full(), g_datalist_set_data() and
107 * g_datalist_set_data_full().
109 * To get data elements from a datalist use g_datalist_id_get_data()
110 * and g_datalist_get_data().
112 * To iterate over all data elements in a datalist use
113 * g_datalist_foreach() (not thread-safe).
115 * To remove data elements from a datalist use
116 * g_datalist_id_remove_data() and g_datalist_remove_data().
118 * To remove all data elements from a datalist, use g_datalist_clear().
122 * GData:
124 * The #GData struct is an opaque data structure to represent a <link
125 * linkend="glib-Keyed-Data-Lists">Keyed Data List</link>. It should
126 * only be accessed via the following functions.
130 * GDestroyNotify:
131 * @data: the data element.
133 * Specifies the type of function which is called when a data element
134 * is destroyed. It is passed the pointer to the data element and
135 * should free any memory and resources allocated for it.
138 /* --- defines --- */
139 #define G_QUARK_BLOCK_SIZE (2048)
141 #define G_DATALIST_FLAGS_MASK_INTERNAL 0x7
143 /* datalist pointer accesses have to be carried out atomically */
144 #define G_DATALIST_GET_POINTER(datalist) \
145 ((GData*) ((gsize) g_atomic_pointer_get (datalist) & ~(gsize) G_DATALIST_FLAGS_MASK_INTERNAL))
147 #define G_DATALIST_SET_POINTER(datalist, pointer) G_STMT_START { \
148 gpointer _oldv, _newv; \
149 do { \
150 _oldv = g_atomic_pointer_get (datalist); \
151 _newv = (gpointer) (((gsize) _oldv & G_DATALIST_FLAGS_MASK_INTERNAL) | (gsize) pointer); \
152 } while (!g_atomic_pointer_compare_and_exchange ((void**) datalist, _oldv, _newv)); \
153 } G_STMT_END
155 /* --- structures --- */
156 typedef struct {
157 GQuark key;
158 gpointer data;
159 GDestroyNotify destroy;
160 } GDataElt;
162 typedef struct _GDataset GDataset;
163 struct _GData
165 guint32 len; /* Number of elements */
166 guint32 alloc; /* Number of allocated elements */
167 GDataElt data[1]; /* Flexible array */
170 struct _GDataset
172 gconstpointer location;
173 GData *datalist;
177 /* --- prototypes --- */
178 static inline GDataset* g_dataset_lookup (gconstpointer dataset_location);
179 static inline void g_datalist_clear_i (GData **datalist);
180 static void g_dataset_destroy_internal (GDataset *dataset);
181 static inline gpointer g_data_set_internal (GData **datalist,
182 GQuark key_id,
183 gpointer data,
184 GDestroyNotify destroy_func,
185 GDataset *dataset);
186 static void g_data_initialize (void);
187 static inline GQuark g_quark_new (gchar *string);
190 /* Locking model:
191 * Each standalone GDataList is protected by a bitlock in the datalist pointer,
192 * which protects that modification of the non-flags part of the datalist pointer
193 * and the contents of the datalist.
195 * For GDataSet we have a global lock g_dataset_global that protects
196 * the global dataset hash and cache, and additionally it protects the
197 * datalist such that we can avoid to use the bit lock in a few places
198 * where it is easy.
201 /* --- variables --- */
202 G_LOCK_DEFINE_STATIC (g_dataset_global);
203 static GHashTable *g_dataset_location_ht = NULL;
204 static GDataset *g_dataset_cached = NULL; /* should this be
205 threadspecific? */
206 G_LOCK_DEFINE_STATIC (g_quark_global);
207 static GHashTable *g_quark_ht = NULL;
208 static gchar **g_quarks = NULL;
209 static int g_quark_seq_id = 0;
211 /* --- functions --- */
213 #define DATALIST_LOCK_BIT 2
215 static void
216 g_datalist_lock (GData **datalist)
218 g_pointer_bit_lock ((void **)datalist, DATALIST_LOCK_BIT);
221 static void
222 g_datalist_unlock (GData **datalist)
224 g_pointer_bit_unlock ((void **)datalist, DATALIST_LOCK_BIT);
227 /* Called with the datalist lock held, or the dataset global
228 * lock for dataset lists
230 static void
231 g_datalist_clear_i (GData **datalist)
233 GData *data;
234 gint i;
236 data = G_DATALIST_GET_POINTER (datalist);
237 G_DATALIST_SET_POINTER (datalist, NULL);
239 if (data)
241 G_UNLOCK (g_dataset_global);
242 for (i = 0; i < data->len; i++)
244 if (data->data[i].data && data->data[i].destroy)
245 data->data[i].destroy (data->data[i].data);
247 G_LOCK (g_dataset_global);
249 g_free (data);
255 * g_datalist_clear:
256 * @datalist: a datalist.
258 * Frees all the data elements of the datalist.
259 * The data elements' destroy functions are called
260 * if they have been set.
262 void
263 g_datalist_clear (GData **datalist)
265 GData *data;
266 gint i;
268 g_return_if_fail (datalist != NULL);
270 g_datalist_lock (datalist);
272 data = G_DATALIST_GET_POINTER (datalist);
273 G_DATALIST_SET_POINTER (datalist, NULL);
275 g_datalist_unlock (datalist);
277 if (data)
279 for (i = 0; i < data->len; i++)
281 if (data->data[i].data && data->data[i].destroy)
282 data->data[i].destroy (data->data[i].data);
285 g_free (data);
289 /* HOLDS: g_dataset_global_lock */
290 static inline GDataset*
291 g_dataset_lookup (gconstpointer dataset_location)
293 register GDataset *dataset;
295 if (g_dataset_cached && g_dataset_cached->location == dataset_location)
296 return g_dataset_cached;
298 dataset = g_hash_table_lookup (g_dataset_location_ht, dataset_location);
299 if (dataset)
300 g_dataset_cached = dataset;
302 return dataset;
305 /* HOLDS: g_dataset_global_lock */
306 static void
307 g_dataset_destroy_internal (GDataset *dataset)
309 register gconstpointer dataset_location;
311 dataset_location = dataset->location;
312 while (dataset)
314 if (G_DATALIST_GET_POINTER(&dataset->datalist) == NULL)
316 if (dataset == g_dataset_cached)
317 g_dataset_cached = NULL;
318 g_hash_table_remove (g_dataset_location_ht, dataset_location);
319 g_slice_free (GDataset, dataset);
320 break;
323 g_datalist_clear_i (&dataset->datalist);
324 dataset = g_dataset_lookup (dataset_location);
329 * g_dataset_destroy:
330 * @dataset_location: the location identifying the dataset.
332 * Destroys the dataset, freeing all memory allocated, and calling any
333 * destroy functions set for data elements.
335 void
336 g_dataset_destroy (gconstpointer dataset_location)
338 g_return_if_fail (dataset_location != NULL);
340 G_LOCK (g_dataset_global);
341 if (g_dataset_location_ht)
343 register GDataset *dataset;
345 dataset = g_dataset_lookup (dataset_location);
346 if (dataset)
347 g_dataset_destroy_internal (dataset);
349 G_UNLOCK (g_dataset_global);
352 /* HOLDS: g_dataset_global_lock if dataset != null */
353 static inline gpointer
354 g_data_set_internal (GData **datalist,
355 GQuark key_id,
356 gpointer new_data,
357 GDestroyNotify new_destroy_func,
358 GDataset *dataset)
360 GData *d, *old_d;
361 GDataElt old, *data, *data_last, *data_end;
363 g_datalist_lock (datalist);
365 d = G_DATALIST_GET_POINTER (datalist);
367 if (new_data == NULL) /* remove */
369 if (d)
371 data = d->data;
372 data_last = data + d->len - 1;
373 while (data <= data_last)
375 if (data->key == key_id)
377 old = *data;
378 if (data != data_last)
379 *data = *data_last;
380 d->len--;
382 /* We don't bother to shrink, but if all data are now gone
383 * we at least free the memory
385 if (d->len == 0)
387 G_DATALIST_SET_POINTER (datalist, NULL);
388 g_free (d);
390 /* the dataset destruction *must* be done
391 * prior to invocation of the data destroy function
393 if (dataset)
394 g_dataset_destroy_internal (dataset);
397 g_datalist_unlock (datalist);
399 /* We found and removed an old value
400 * the GData struct *must* already be unlinked
401 * when invoking the destroy function.
402 * we use (new_data==NULL && new_destroy_func!=NULL) as
403 * a special hint combination to "steal"
404 * data without destroy notification
406 if (old.destroy && !new_destroy_func)
408 if (dataset)
409 G_UNLOCK (g_dataset_global);
410 old.destroy (old.data);
411 if (dataset)
412 G_LOCK (g_dataset_global);
413 old.data = NULL;
416 return old.data;
418 data++;
422 else
424 old.data = NULL;
425 if (d)
427 data = d->data;
428 data_end = data + d->len;
429 while (data < data_end)
431 if (data->key == key_id)
433 if (!data->destroy)
435 data->data = new_data;
436 data->destroy = new_destroy_func;
437 g_datalist_unlock (datalist);
439 else
441 old = *data;
442 data->data = new_data;
443 data->destroy = new_destroy_func;
445 g_datalist_unlock (datalist);
447 /* We found and replaced an old value
448 * the GData struct *must* already be unlinked
449 * when invoking the destroy function.
451 if (dataset)
452 G_UNLOCK (g_dataset_global);
453 old.destroy (old.data);
454 if (dataset)
455 G_LOCK (g_dataset_global);
457 return NULL;
459 data++;
463 /* The key was not found, insert it */
464 old_d = d;
465 if (d == NULL)
467 d = g_malloc (sizeof (GData));
468 d->len = 0;
469 d->alloc = 1;
471 else if (d->len == d->alloc)
473 d->alloc = d->alloc * 2;
474 d = g_realloc (d, sizeof (GData) + (d->alloc - 1) * sizeof (GDataElt));
476 if (old_d != d)
477 G_DATALIST_SET_POINTER (datalist, d);
479 d->data[d->len].key = key_id;
480 d->data[d->len].data = new_data;
481 d->data[d->len].destroy = new_destroy_func;
482 d->len++;
485 g_datalist_unlock (datalist);
487 return NULL;
492 * g_dataset_id_set_data_full:
493 * @dataset_location: the location identifying the dataset.
494 * @key_id: the #GQuark id to identify the data element.
495 * @data: the data element.
496 * @destroy_func: the function to call when the data element is
497 * removed. This function will be called with the data
498 * element and can be used to free any memory allocated
499 * for it.
501 * Sets the data element associated with the given #GQuark id, and also
502 * the function to call when the data element is destroyed. Any
503 * previous data with the same key is removed, and its destroy function
504 * is called.
507 * g_dataset_set_data_full:
508 * @l: the location identifying the dataset.
509 * @k: the string to identify the data element.
510 * @d: the data element.
511 * @f: the function to call when the data element is removed. This
512 * function will be called with the data element and can be used to
513 * free any memory allocated for it.
515 * Sets the data corresponding to the given string identifier, and the
516 * function to call when the data element is destroyed.
519 * g_dataset_id_set_data:
520 * @l: the location identifying the dataset.
521 * @k: the #GQuark id to identify the data element.
522 * @d: the data element.
524 * Sets the data element associated with the given #GQuark id. Any
525 * previous data with the same key is removed, and its destroy function
526 * is called.
529 * g_dataset_set_data:
530 * @l: the location identifying the dataset.
531 * @k: the string to identify the data element.
532 * @d: the data element.
534 * Sets the data corresponding to the given string identifier.
537 * g_dataset_id_remove_data:
538 * @l: the location identifying the dataset.
539 * @k: the #GQuark id identifying the data element.
541 * Removes a data element from a dataset. The data element's destroy
542 * function is called if it has been set.
545 * g_dataset_remove_data:
546 * @l: the location identifying the dataset.
547 * @k: the string identifying the data element.
549 * Removes a data element corresponding to a string. Its destroy
550 * function is called if it has been set.
552 void
553 g_dataset_id_set_data_full (gconstpointer dataset_location,
554 GQuark key_id,
555 gpointer data,
556 GDestroyNotify destroy_func)
558 register GDataset *dataset;
560 g_return_if_fail (dataset_location != NULL);
561 if (!data)
562 g_return_if_fail (destroy_func == NULL);
563 if (!key_id)
565 if (data)
566 g_return_if_fail (key_id > 0);
567 else
568 return;
571 G_LOCK (g_dataset_global);
572 if (!g_dataset_location_ht)
573 g_data_initialize ();
575 dataset = g_dataset_lookup (dataset_location);
576 if (!dataset)
578 dataset = g_slice_new (GDataset);
579 dataset->location = dataset_location;
580 g_datalist_init (&dataset->datalist);
581 g_hash_table_insert (g_dataset_location_ht,
582 (gpointer) dataset->location,
583 dataset);
586 g_data_set_internal (&dataset->datalist, key_id, data, destroy_func, dataset);
587 G_UNLOCK (g_dataset_global);
591 * g_datalist_id_set_data_full:
592 * @datalist: a datalist.
593 * @key_id: the #GQuark to identify the data element.
594 * @data: the data element or %NULL to remove any previous element
595 * corresponding to @key_id.
596 * @destroy_func: the function to call when the data element is
597 * removed. This function will be called with the data
598 * element and can be used to free any memory allocated
599 * for it. If @data is %NULL, then @destroy_func must
600 * also be %NULL.
602 * Sets the data corresponding to the given #GQuark id, and the
603 * function to be called when the element is removed from the datalist.
604 * Any previous data with the same key is removed, and its destroy
605 * function is called.
608 * g_datalist_set_data_full:
609 * @dl: a datalist.
610 * @k: the string to identify the data element.
611 * @d: the data element, or %NULL to remove any previous element
612 * corresponding to @k.
613 * @f: the function to call when the data element is removed. This
614 * function will be called with the data element and can be used to
615 * free any memory allocated for it. If @d is %NULL, then @f must
616 * also be %NULL.
618 * Sets the data element corresponding to the given string identifier,
619 * and the function to be called when the data element is removed.
622 * g_datalist_id_set_data:
623 * @dl: a datalist.
624 * @q: the #GQuark to identify the data element.
625 * @d: the data element, or %NULL to remove any previous element
626 * corresponding to @q.
628 * Sets the data corresponding to the given #GQuark id. Any previous
629 * data with the same key is removed, and its destroy function is
630 * called.
633 * g_datalist_set_data:
634 * @dl: a datalist.
635 * @k: the string to identify the data element.
636 * @d: the data element, or %NULL to remove any previous element
637 * corresponding to @k.
639 * Sets the data element corresponding to the given string identifier.
642 * g_datalist_id_remove_data:
643 * @dl: a datalist.
644 * @q: the #GQuark identifying the data element.
646 * Removes an element, using its #GQuark identifier.
649 * g_datalist_remove_data:
650 * @dl: a datalist.
651 * @k: the string identifying the data element.
653 * Removes an element using its string identifier. The data element's
654 * destroy function is called if it has been set.
656 void
657 g_datalist_id_set_data_full (GData **datalist,
658 GQuark key_id,
659 gpointer data,
660 GDestroyNotify destroy_func)
662 g_return_if_fail (datalist != NULL);
663 if (!data)
664 g_return_if_fail (destroy_func == NULL);
665 if (!key_id)
667 if (data)
668 g_return_if_fail (key_id > 0);
669 else
670 return;
673 g_data_set_internal (datalist, key_id, data, destroy_func, NULL);
677 * g_dataset_id_remove_no_notify:
678 * @dataset_location: the location identifying the dataset.
679 * @key_id: the #GQuark ID identifying the data element.
680 * @Returns: the data previously stored at @key_id, or %NULL if none.
682 * Removes an element, without calling its destroy notification
683 * function.
686 * g_dataset_remove_no_notify:
687 * @l: the location identifying the dataset.
688 * @k: the string identifying the data element.
690 * Removes an element, without calling its destroy notifier.
692 gpointer
693 g_dataset_id_remove_no_notify (gconstpointer dataset_location,
694 GQuark key_id)
696 gpointer ret_data = NULL;
698 g_return_val_if_fail (dataset_location != NULL, NULL);
700 G_LOCK (g_dataset_global);
701 if (key_id && g_dataset_location_ht)
703 GDataset *dataset;
705 dataset = g_dataset_lookup (dataset_location);
706 if (dataset)
707 ret_data = g_data_set_internal (&dataset->datalist, key_id, NULL, (GDestroyNotify) 42, dataset);
709 G_UNLOCK (g_dataset_global);
711 return ret_data;
715 * g_datalist_id_remove_no_notify:
716 * @datalist: a datalist.
717 * @key_id: the #GQuark identifying a data element.
718 * @Returns: the data previously stored at @key_id, or %NULL if none.
720 * Removes an element, without calling its destroy notification
721 * function.
724 * g_datalist_remove_no_notify:
725 * @dl: a datalist.
726 * @k: the string identifying the data element.
728 * Removes an element, without calling its destroy notifier.
730 gpointer
731 g_datalist_id_remove_no_notify (GData **datalist,
732 GQuark key_id)
734 gpointer ret_data = NULL;
736 g_return_val_if_fail (datalist != NULL, NULL);
738 if (key_id)
739 ret_data = g_data_set_internal (datalist, key_id, NULL, (GDestroyNotify) 42, NULL);
741 return ret_data;
745 * g_dataset_id_get_data:
746 * @dataset_location: the location identifying the dataset.
747 * @key_id: the #GQuark id to identify the data element.
748 * @Returns: the data element corresponding to the #GQuark, or %NULL if
749 * it is not found.
751 * Gets the data element corresponding to a #GQuark.
754 * g_dataset_get_data:
755 * @l: the location identifying the dataset.
756 * @k: the string identifying the data element.
757 * @Returns: the data element corresponding to the string, or %NULL if
758 * it is not found.
760 * Gets the data element corresponding to a string.
762 gpointer
763 g_dataset_id_get_data (gconstpointer dataset_location,
764 GQuark key_id)
766 gpointer retval = NULL;
768 g_return_val_if_fail (dataset_location != NULL, NULL);
770 G_LOCK (g_dataset_global);
771 if (key_id && g_dataset_location_ht)
773 GDataset *dataset;
775 dataset = g_dataset_lookup (dataset_location);
776 if (dataset)
777 retval = g_datalist_id_get_data (&dataset->datalist, key_id);
779 G_UNLOCK (g_dataset_global);
781 return retval;
785 * g_datalist_id_get_data:
786 * @datalist: a datalist.
787 * @key_id: the #GQuark identifying a data element.
788 * @Returns: the data element, or %NULL if it is not found.
790 * Retrieves the data element corresponding to @key_id.
792 gpointer
793 g_datalist_id_get_data (GData **datalist,
794 GQuark key_id)
796 gpointer res = NULL;
798 g_return_val_if_fail (datalist != NULL, NULL);
799 if (key_id)
801 GData *d;
802 GDataElt *data, *data_end;
804 g_datalist_lock (datalist);
806 d = G_DATALIST_GET_POINTER (datalist);
807 if (d)
809 data = d->data;
810 data_end = data + d->len;
811 while (data < data_end)
813 if (data->key == key_id)
815 res = data->data;
816 break;
818 data++;
822 g_datalist_unlock (datalist);
825 return res;
829 * g_datalist_get_data:
830 * @dl: a datalist.
831 * @k: the string identifying a data element.
832 * @Returns: the data element, or %NULL if it is not found.
834 * Gets a data element, using its string identifer. This is slower than
835 * g_datalist_id_get_data() because it compares strings.
837 gpointer
838 g_datalist_get_data (GData **datalist,
839 const gchar *key)
841 gpointer res = NULL;
842 GData *d;
843 GDataElt *data, *data_end;
845 g_return_val_if_fail (datalist != NULL, NULL);
847 g_datalist_lock (datalist);
849 d = G_DATALIST_GET_POINTER (datalist);
850 if (d)
852 data = d->data;
853 data_end = data + d->len;
854 while (data < data_end)
856 if (strcmp (g_quark_to_string (data->key), key) == 0)
858 res = data->data;
859 break;
861 data++;
865 g_datalist_unlock (datalist);
867 return res;
871 * GDataForeachFunc:
872 * @key_id: the #GQuark id to identifying the data element.
873 * @data: the data element.
874 * @user_data: user data passed to g_dataset_foreach().
876 * Specifies the type of function passed to g_dataset_foreach(). It is
877 * called with each #GQuark id and associated data element, together
878 * with the @user_data parameter supplied to g_dataset_foreach().
882 * g_dataset_foreach:
883 * @dataset_location: the location identifying the dataset.
884 * @func: the function to call for each data element.
885 * @user_data: user data to pass to the function.
887 * Calls the given function for each data element which is associated
888 * with the given location. Note that this function is NOT thread-safe.
889 * So unless @datalist can be protected from any modifications during
890 * invocation of this function, it should not be called.
892 void
893 g_dataset_foreach (gconstpointer dataset_location,
894 GDataForeachFunc func,
895 gpointer user_data)
897 register GDataset *dataset;
899 g_return_if_fail (dataset_location != NULL);
900 g_return_if_fail (func != NULL);
902 G_LOCK (g_dataset_global);
903 if (g_dataset_location_ht)
905 dataset = g_dataset_lookup (dataset_location);
906 G_UNLOCK (g_dataset_global);
907 if (dataset)
908 g_datalist_foreach (&dataset->datalist, func, user_data);
910 else
912 G_UNLOCK (g_dataset_global);
917 * g_datalist_foreach:
918 * @datalist: a datalist.
919 * @func: the function to call for each data element.
920 * @user_data: user data to pass to the function.
922 * Calls the given function for each data element of the datalist. The
923 * function is called with each data element's #GQuark id and data,
924 * together with the given @user_data parameter. Note that this
925 * function is NOT thread-safe. So unless @datalist can be protected
926 * from any modifications during invocation of this function, it should
927 * not be called.
929 void
930 g_datalist_foreach (GData **datalist,
931 GDataForeachFunc func,
932 gpointer user_data)
934 GData *d;
935 int i, j, len;
936 GQuark *keys;
938 g_return_if_fail (datalist != NULL);
939 g_return_if_fail (func != NULL);
941 d = G_DATALIST_GET_POINTER (datalist);
942 if (d == NULL)
943 return;
945 /* We make a copy of the keys so that we can handle it changing
946 in the callback */
947 len = d->len;
948 keys = g_new (GQuark, len);
949 for (i = 0; i < len; i++)
950 keys[i] = d->data[i].key;
952 for (i = 0; i < len; i++)
954 /* A previous callback might have removed a later item, so always check that
955 it still exists before calling */
956 d = G_DATALIST_GET_POINTER (datalist);
958 if (d == NULL)
959 break;
960 for (j = 0; j < d->len; j++)
962 if (d->data[j].key == keys[i]) {
963 func (d->data[i].key, d->data[i].data, user_data);
964 break;
968 g_free (keys);
972 * g_datalist_init:
973 * @datalist: a pointer to a pointer to a datalist.
975 * Resets the datalist to %NULL. It does not free any memory or call
976 * any destroy functions.
978 void
979 g_datalist_init (GData **datalist)
981 g_return_if_fail (datalist != NULL);
983 g_atomic_pointer_set (datalist, NULL);
987 * g_datalist_set_flags:
988 * @datalist: pointer to the location that holds a list
989 * @flags: the flags to turn on. The values of the flags are
990 * restricted by %G_DATALIST_FLAGS_MASK (currently
991 * 3; giving two possible boolean flags).
992 * A value for @flags that doesn't fit within the mask is
993 * an error.
995 * Turns on flag values for a data list. This function is used
996 * to keep a small number of boolean flags in an object with
997 * a data list without using any additional space. It is
998 * not generally useful except in circumstances where space
999 * is very tight. (It is used in the base #GObject type, for
1000 * example.)
1002 * Since: 2.8
1004 void
1005 g_datalist_set_flags (GData **datalist,
1006 guint flags)
1008 g_return_if_fail (datalist != NULL);
1009 g_return_if_fail ((flags & ~G_DATALIST_FLAGS_MASK) == 0);
1011 g_atomic_pointer_or (datalist, (gsize)flags);
1015 * g_datalist_unset_flags:
1016 * @datalist: pointer to the location that holds a list
1017 * @flags: the flags to turn off. The values of the flags are
1018 * restricted by %G_DATALIST_FLAGS_MASK (currently
1019 * 3: giving two possible boolean flags).
1020 * A value for @flags that doesn't fit within the mask is
1021 * an error.
1023 * Turns off flag values for a data list. See g_datalist_unset_flags()
1025 * Since: 2.8
1027 void
1028 g_datalist_unset_flags (GData **datalist,
1029 guint flags)
1031 g_return_if_fail (datalist != NULL);
1032 g_return_if_fail ((flags & ~G_DATALIST_FLAGS_MASK) == 0);
1034 g_atomic_pointer_and (datalist, ~(gsize)flags);
1038 * g_datalist_get_flags:
1039 * @datalist: pointer to the location that holds a list
1041 * Gets flags values packed in together with the datalist.
1042 * See g_datalist_set_flags().
1044 * Return value: the flags of the datalist
1046 * Since: 2.8
1048 guint
1049 g_datalist_get_flags (GData **datalist)
1051 g_return_val_if_fail (datalist != NULL, 0);
1053 return G_DATALIST_GET_FLAGS (datalist); /* atomic macro */
1056 /* HOLDS: g_dataset_global_lock */
1057 static void
1058 g_data_initialize (void)
1060 g_return_if_fail (g_dataset_location_ht == NULL);
1062 g_dataset_location_ht = g_hash_table_new (g_direct_hash, NULL);
1063 g_dataset_cached = NULL;
1067 * SECTION:quarks
1068 * @title: Quarks
1069 * @short_description: a 2-way association between a string and a
1070 * unique integer identifier
1072 * Quarks are associations between strings and integer identifiers.
1073 * Given either the string or the #GQuark identifier it is possible to
1074 * retrieve the other.
1076 * Quarks are used for both <link
1077 * linkend="glib-Datasets">Datasets</link> and <link
1078 * linkend="glib-Keyed-Data-Lists">Keyed Data Lists</link>.
1080 * To create a new quark from a string, use g_quark_from_string() or
1081 * g_quark_from_static_string().
1083 * To find the string corresponding to a given #GQuark, use
1084 * g_quark_to_string().
1086 * To find the #GQuark corresponding to a given string, use
1087 * g_quark_try_string().
1089 * Another use for the string pool maintained for the quark functions
1090 * is string interning, using g_intern_string() or
1091 * g_intern_static_string(). An interned string is a canonical
1092 * representation for a string. One important advantage of interned
1093 * strings is that they can be compared for equality by a simple
1094 * pointer comparision, rather than using strcmp().
1098 * GQuark:
1100 * A GQuark is a non-zero integer which uniquely identifies a
1101 * particular string. A GQuark value of zero is associated to %NULL.
1105 * g_quark_try_string:
1106 * @string: a string.
1107 * @Returns: the #GQuark associated with the string, or 0 if @string is
1108 * %NULL or there is no #GQuark associated with it.
1110 * Gets the #GQuark associated with the given string, or 0 if string is
1111 * %NULL or it has no associated #GQuark.
1113 * If you want the GQuark to be created if it doesn't already exist,
1114 * use g_quark_from_string() or g_quark_from_static_string().
1116 GQuark
1117 g_quark_try_string (const gchar *string)
1119 GQuark quark = 0;
1121 if (string == NULL)
1122 return 0;
1124 G_LOCK (g_quark_global);
1125 if (g_quark_ht)
1126 quark = GPOINTER_TO_UINT (g_hash_table_lookup (g_quark_ht, string));
1127 G_UNLOCK (g_quark_global);
1129 return quark;
1132 #define QUARK_STRING_BLOCK_SIZE (4096 - sizeof (gsize))
1133 static char *quark_block = NULL;
1134 static int quark_block_offset = 0;
1136 /* HOLDS: g_quark_global_lock */
1137 static char *
1138 quark_strdup(const gchar *string)
1140 gchar *copy;
1141 gsize len;
1143 len = strlen (string) + 1;
1145 /* For strings longer than half the block size, fall back
1146 to strdup so that we fill our blocks at least 50%. */
1147 if (len > QUARK_STRING_BLOCK_SIZE / 2)
1148 return g_strdup (string);
1150 if (quark_block == NULL ||
1151 QUARK_STRING_BLOCK_SIZE - quark_block_offset < len)
1153 quark_block = g_malloc (QUARK_STRING_BLOCK_SIZE);
1154 quark_block_offset = 0;
1157 copy = quark_block + quark_block_offset;
1158 memcpy (copy, string, len);
1159 quark_block_offset += len;
1161 return copy;
1164 /* HOLDS: g_quark_global_lock */
1165 static inline GQuark
1166 g_quark_from_string_internal (const gchar *string,
1167 gboolean duplicate)
1169 GQuark quark = 0;
1171 if (g_quark_ht)
1172 quark = GPOINTER_TO_UINT (g_hash_table_lookup (g_quark_ht, string));
1174 if (!quark)
1176 quark = g_quark_new (duplicate ? quark_strdup (string) : (gchar *)string);
1177 TRACE(GLIB_QUARK_NEW(string, quark));
1180 return quark;
1184 * g_quark_from_string:
1185 * @string: a string.
1186 * @Returns: the #GQuark identifying the string, or 0 if @string is
1187 * %NULL.
1189 * Gets the #GQuark identifying the given string. If the string does
1190 * not currently have an associated #GQuark, a new #GQuark is created,
1191 * using a copy of the string.
1193 GQuark
1194 g_quark_from_string (const gchar *string)
1196 GQuark quark;
1198 if (!string)
1199 return 0;
1201 G_LOCK (g_quark_global);
1202 quark = g_quark_from_string_internal (string, TRUE);
1203 G_UNLOCK (g_quark_global);
1205 return quark;
1209 * g_quark_from_static_string:
1210 * @string: a string.
1211 * @Returns: the #GQuark identifying the string, or 0 if @string is
1212 * %NULL.
1214 * Gets the #GQuark identifying the given (static) string. If the
1215 * string does not currently have an associated #GQuark, a new #GQuark
1216 * is created, linked to the given string.
1218 * Note that this function is identical to g_quark_from_string() except
1219 * that if a new #GQuark is created the string itself is used rather
1220 * than a copy. This saves memory, but can only be used if the string
1221 * will <emphasis>always</emphasis> exist. It can be used with
1222 * statically allocated strings in the main program, but not with
1223 * statically allocated memory in dynamically loaded modules, if you
1224 * expect to ever unload the module again (e.g. do not use this
1225 * function in GTK+ theme engines).
1227 GQuark
1228 g_quark_from_static_string (const gchar *string)
1230 GQuark quark;
1232 if (!string)
1233 return 0;
1235 G_LOCK (g_quark_global);
1236 quark = g_quark_from_string_internal (string, FALSE);
1237 G_UNLOCK (g_quark_global);
1239 return quark;
1243 * g_quark_to_string:
1244 * @quark: a #GQuark.
1245 * @Returns: the string associated with the #GQuark.
1247 * Gets the string associated with the given #GQuark.
1249 const gchar *
1250 g_quark_to_string (GQuark quark)
1252 gchar* result = NULL;
1253 gchar **quarks;
1254 gint quark_seq_id;
1256 quark_seq_id = g_atomic_int_get (&g_quark_seq_id);
1257 quarks = g_atomic_pointer_get (&g_quarks);
1259 if (quark < quark_seq_id)
1260 result = quarks[quark];
1262 return result;
1265 /* HOLDS: g_quark_global_lock */
1266 static inline GQuark
1267 g_quark_new (gchar *string)
1269 GQuark quark;
1270 gchar **g_quarks_new;
1272 if (g_quark_seq_id % G_QUARK_BLOCK_SIZE == 0)
1274 g_quarks_new = g_new (gchar*, g_quark_seq_id + G_QUARK_BLOCK_SIZE);
1275 if (g_quark_seq_id != 0)
1276 memcpy (g_quarks_new, g_quarks, sizeof (char *) * g_quark_seq_id);
1277 memset (g_quarks_new + g_quark_seq_id, 0, sizeof (char *) * G_QUARK_BLOCK_SIZE);
1278 /* This leaks the old quarks array. Its unfortunate, but it allows
1279 us to do lockless lookup of the arrays, and there shouldn't be that
1280 many quarks in an app */
1281 g_atomic_pointer_set (&g_quarks, g_quarks_new);
1283 if (!g_quark_ht)
1285 g_assert (g_quark_seq_id == 0);
1286 g_quark_ht = g_hash_table_new (g_str_hash, g_str_equal);
1287 g_quarks[g_quark_seq_id] = NULL;
1288 g_atomic_int_inc (&g_quark_seq_id);
1291 quark = g_quark_seq_id;
1292 g_atomic_pointer_set (&g_quarks[quark], string);
1293 g_hash_table_insert (g_quark_ht, string, GUINT_TO_POINTER (quark));
1294 g_atomic_int_inc (&g_quark_seq_id);
1296 return quark;
1300 * g_intern_string:
1301 * @string: a string
1303 * Returns a canonical representation for @string. Interned strings can
1304 * be compared for equality by comparing the pointers, instead of using strcmp().
1306 * Returns: a canonical representation for the string
1308 * Since: 2.10
1310 const gchar *
1311 g_intern_string (const gchar *string)
1313 const gchar *result;
1314 GQuark quark;
1316 if (!string)
1317 return NULL;
1319 G_LOCK (g_quark_global);
1320 quark = g_quark_from_string_internal (string, TRUE);
1321 result = g_quarks[quark];
1322 G_UNLOCK (g_quark_global);
1324 return result;
1328 * g_intern_static_string:
1329 * @string: a static string
1331 * Returns a canonical representation for @string. Interned strings can
1332 * be compared for equality by comparing the pointers, instead of using strcmp().
1333 * g_intern_static_string() does not copy the string, therefore @string must
1334 * not be freed or modified.
1336 * Returns: a canonical representation for the string
1338 * Since: 2.10
1340 const gchar *
1341 g_intern_static_string (const gchar *string)
1343 GQuark quark;
1344 const gchar *result;
1346 if (!string)
1347 return NULL;
1349 G_LOCK (g_quark_global);
1350 quark = g_quark_from_string_internal (string, FALSE);
1351 result = g_quarks[quark];
1352 G_UNLOCK (g_quark_global);
1354 return result;