diff options
83 files changed, 1026 insertions, 61 deletions
@@ -1,3 +1,18 @@ +2005-05-05 Owen Taylor <otaylor@redhat.com> + + * glib/gdataset.[ch] glib/gdatasetprivate.h: Add + g_datalist_set/unset_flags(), g_datalist_get_flags() functions + to squeeze some bits into a GDataSet... this is needed for + efficient implementation of toggle references in GObject. + + * tests/gobject/references.c tests/gobject/Makefile.am: + Add a test case for weak and toggle references. + + * glib/gfileutils.[ch]: Rename g_file_replace() back + to g_file_set_contents(). + + * glib/glib.symbols: Update. + 2005-05-02 Matthias Clasen <mclasen@redhat.com> * glib/gstring.c (g_str_equal, g_str_hash): Move docs diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 19a94687b..fbc9501d7 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,18 @@ +2005-05-05 Owen Taylor <otaylor@redhat.com> + + * glib/gdataset.[ch] glib/gdatasetprivate.h: Add + g_datalist_set/unset_flags(), g_datalist_get_flags() functions + to squeeze some bits into a GDataSet... this is needed for + efficient implementation of toggle references in GObject. + + * tests/gobject/references.c tests/gobject/Makefile.am: + Add a test case for weak and toggle references. + + * glib/gfileutils.[ch]: Rename g_file_replace() back + to g_file_set_contents(). + + * glib/glib.symbols: Update. + 2005-05-02 Matthias Clasen <mclasen@redhat.com> * glib/gstring.c (g_str_equal, g_str_hash): Move docs diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index 19a94687b..fbc9501d7 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,3 +1,18 @@ +2005-05-05 Owen Taylor <otaylor@redhat.com> + + * glib/gdataset.[ch] glib/gdatasetprivate.h: Add + g_datalist_set/unset_flags(), g_datalist_get_flags() functions + to squeeze some bits into a GDataSet... this is needed for + efficient implementation of toggle references in GObject. + + * tests/gobject/references.c tests/gobject/Makefile.am: + Add a test case for weak and toggle references. + + * glib/gfileutils.[ch]: Rename g_file_replace() back + to g_file_set_contents(). + + * glib/glib.symbols: Update. + 2005-05-02 Matthias Clasen <mclasen@redhat.com> * glib/gstring.c (g_str_equal, g_str_hash): Move docs diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 19a94687b..fbc9501d7 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,18 @@ +2005-05-05 Owen Taylor <otaylor@redhat.com> + + * glib/gdataset.[ch] glib/gdatasetprivate.h: Add + g_datalist_set/unset_flags(), g_datalist_get_flags() functions + to squeeze some bits into a GDataSet... this is needed for + efficient implementation of toggle references in GObject. + + * tests/gobject/references.c tests/gobject/Makefile.am: + Add a test case for weak and toggle references. + + * glib/gfileutils.[ch]: Rename g_file_replace() back + to g_file_set_contents(). + + * glib/glib.symbols: Update. + 2005-05-02 Matthias Clasen <mclasen@redhat.com> * glib/gstring.c (g_str_equal, g_str_hash): Move docs diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog index bda5fd3d1..6511da76a 100644 --- a/docs/reference/ChangeLog +++ b/docs/reference/ChangeLog @@ -1,3 +1,10 @@ +2005-05-05 Owen Taylor <otaylor@redhat.com> + + * glib/Makefile.am glib/glib-sections.txt gobject/gobject-sections.txt: + Update + + * gobject/tmpl/objects.sgml: Document toggle-references. + 2005-05-02 Matthias Clasen <mclasen@redhat.com> * glib/tmpl/hash_tables.sgml: Move some docs inline. diff --git a/docs/reference/glib/Makefile.am b/docs/reference/glib/Makefile.am index aac0f9ee3..45fa09928 100644 --- a/docs/reference/glib/Makefile.am +++ b/docs/reference/glib/Makefile.am @@ -22,6 +22,7 @@ IGNORE_HFILES= \ build \ gobject \ config.h \ + gdatasetprivate.h \ glibintl.h \ gbsearcharray.h \ gmoduleconf.h \ diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt index e1f0d09f5..9a5f8bb41 100644 --- a/docs/reference/glib/glib-sections.txt +++ b/docs/reference/glib/glib-sections.txt @@ -980,7 +980,7 @@ G_FILE_ERROR GFileTest g_file_error_from_errno g_file_get_contents -g_file_replace +g_file_set_contents g_file_test g_mkstemp g_file_open_tmp @@ -1345,6 +1345,7 @@ g_nullify_pointer <SUBSECTION Private> G_NATIVE_ATEXIT g_ATEXIT +g_win32_get_system_data_dirs_for_module ATEXIT </SECTION> @@ -1970,6 +1971,10 @@ g_datalist_remove_no_notify <SUBSECTION> g_datalist_foreach g_datalist_clear +g_datalist_set_flags +g_datalist_unset_flags +g_datalist_get_flags +G_DATALIST_FLAGS_MASK </SECTION> diff --git a/docs/reference/glib/tmpl/allocators.sgml b/docs/reference/glib/tmpl/allocators.sgml index a98496c81..54eb60bbb 100644 --- a/docs/reference/glib/tmpl/allocators.sgml +++ b/docs/reference/glib/tmpl/allocators.sgml @@ -34,6 +34,9 @@ elements. Each must use separate allocators. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GAllocator ##### --> <para> The <structname>GAllocator</structname> struct contains private data. and should only be accessed diff --git a/docs/reference/glib/tmpl/arrays.sgml b/docs/reference/glib/tmpl/arrays.sgml index 86dd0f269..47092c19d 100644 --- a/docs/reference/glib/tmpl/arrays.sgml +++ b/docs/reference/glib/tmpl/arrays.sgml @@ -55,6 +55,9 @@ To free an array, use g_array_free(). </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GArray ##### --> <para> Contains the public fields of an <link linkend="glib-arrays">Array</link>. diff --git a/docs/reference/glib/tmpl/arrays_pointer.sgml b/docs/reference/glib/tmpl/arrays_pointer.sgml index a1b23a524..0c912d9fb 100644 --- a/docs/reference/glib/tmpl/arrays_pointer.sgml +++ b/docs/reference/glib/tmpl/arrays_pointer.sgml @@ -60,6 +60,9 @@ To free a pointer array, use g_ptr_array_free(). </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GPtrArray ##### --> <para> Contains the public fields of a pointer array. diff --git a/docs/reference/glib/tmpl/async_queues.sgml b/docs/reference/glib/tmpl/async_queues.sgml index b9ffef313..d25642199 100644 --- a/docs/reference/glib/tmpl/async_queues.sgml +++ b/docs/reference/glib/tmpl/async_queues.sgml @@ -63,6 +63,9 @@ locking function variants (those without the suffix _unlocked) </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GAsyncQueue ##### --> <para> The #GAsyncQueue struct is an opaque data structure, which represents diff --git a/docs/reference/glib/tmpl/atomic_operations.sgml b/docs/reference/glib/tmpl/atomic_operations.sgml index bccb0fe36..7025080ef 100644 --- a/docs/reference/glib/tmpl/atomic_operations.sgml +++ b/docs/reference/glib/tmpl/atomic_operations.sgml @@ -60,6 +60,9 @@ g_atomic_pointer_compare_and_exchange() respectively. </variablelist> </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### FUNCTION g_atomic_int_get ##### --> <para> Reads the value of the integer pointed to by @atomic. Also acts as diff --git a/docs/reference/glib/tmpl/byte_order.sgml b/docs/reference/glib/tmpl/byte_order.sgml index 01e931c9a..3006a48e2 100644 --- a/docs/reference/glib/tmpl/byte_order.sgml +++ b/docs/reference/glib/tmpl/byte_order.sgml @@ -44,6 +44,9 @@ as the standard byte order (which is in fact the big-endian byte order). </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### MACRO G_BYTE_ORDER ##### --> <para> The host byte order. diff --git a/docs/reference/glib/tmpl/caches.sgml b/docs/reference/glib/tmpl/caches.sgml index 71b8b6fc9..bdda2116d 100644 --- a/docs/reference/glib/tmpl/caches.sgml +++ b/docs/reference/glib/tmpl/caches.sgml @@ -26,6 +26,9 @@ A #GCache value is the actual resource. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GCache ##### --> <para> The #GCache struct is an opaque data structure containing information about diff --git a/docs/reference/glib/tmpl/conversions.sgml b/docs/reference/glib/tmpl/conversions.sgml index 9f9238788..41a633216 100644 --- a/docs/reference/glib/tmpl/conversions.sgml +++ b/docs/reference/glib/tmpl/conversions.sgml @@ -161,6 +161,9 @@ export G_FILENAME_ENCODING=ISO-8859-1 </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### FUNCTION g_convert ##### --> <para> diff --git a/docs/reference/glib/tmpl/datalist.sgml b/docs/reference/glib/tmpl/datalist.sgml index fea61b65e..c2690ea4a 100644 --- a/docs/reference/glib/tmpl/datalist.sgml +++ b/docs/reference/glib/tmpl/datalist.sgml @@ -47,6 +47,9 @@ To remove all data elements from a datalist, use g_datalist_clear(). </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GData ##### --> <para> The #GData struct is an opaque data structure to represent a @@ -202,3 +205,37 @@ The data elements' destroy functions are called if they have been set. @datalist: a datalist. +<!-- ##### FUNCTION g_datalist_set_flags ##### --> +<para> + +</para> + +@datalist: +@flags: + + +<!-- ##### FUNCTION g_datalist_unset_flags ##### --> +<para> + +</para> + +@datalist: +@flags: + + +<!-- ##### FUNCTION g_datalist_get_flags ##### --> +<para> + +</para> + +@datalist: +@Returns: + + +<!-- ##### MACRO G_DATALIST_FLAGS_MASK ##### --> +<para> + +</para> + + + diff --git a/docs/reference/glib/tmpl/datasets.sgml b/docs/reference/glib/tmpl/datasets.sgml index 1afdf6cf3..815294c50 100644 --- a/docs/reference/glib/tmpl/datasets.sgml +++ b/docs/reference/glib/tmpl/datasets.sgml @@ -49,6 +49,9 @@ To destroy a dataset, use g_dataset_destroy(). </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### MACRO g_dataset_id_set_data ##### --> <para> Sets the data element associated with the given #GQuark id. diff --git a/docs/reference/glib/tmpl/date.sgml b/docs/reference/glib/tmpl/date.sgml index 046265b82..57d9cc87c 100644 --- a/docs/reference/glib/tmpl/date.sgml +++ b/docs/reference/glib/tmpl/date.sgml @@ -63,6 +63,9 @@ can request the current time as a #GTimeVal with g_get_current_time(). </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### MACRO G_USEC_PER_SEC ##### --> <para> Number of microseconds in one second (1 million). This macro is provided for diff --git a/docs/reference/glib/tmpl/error_reporting.sgml b/docs/reference/glib/tmpl/error_reporting.sgml index 6b555a1a7..fa1604e9c 100644 --- a/docs/reference/glib/tmpl/error_reporting.sgml +++ b/docs/reference/glib/tmpl/error_reporting.sgml @@ -370,6 +370,9 @@ Summary of rules for use of #GError: </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GError ##### --> <para> The <structname>GError</structname> structure contains diff --git a/docs/reference/glib/tmpl/fileutils.sgml b/docs/reference/glib/tmpl/fileutils.sgml index e7deae884..63549f2ad 100644 --- a/docs/reference/glib/tmpl/fileutils.sgml +++ b/docs/reference/glib/tmpl/fileutils.sgml @@ -38,6 +38,9 @@ g_dir_read_name(), g_dir_rewind(), g_dir_close(). </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### ENUM GFileError ##### --> <para> Values corresponding to <literal>errno</literal> codes returned from file operations @@ -165,6 +168,18 @@ A test to perform on a file using g_file_test(). @Returns: +<!-- ##### FUNCTION g_file_set_contents ##### --> +<para> + +</para> + +@filename: +@contents: +@length: +@error: +@Returns: + + <!-- ##### FUNCTION g_file_test ##### --> <para> @@ -346,3 +361,33 @@ An opaque structure representing an opened directory. @Returns: +<!-- ##### FUNCTION g_chmod ##### --> +<para> + +</para> + +@filename: +@mode: +@Returns: + + +<!-- ##### FUNCTION g_access ##### --> +<para> + +</para> + +@filename: +@mode: +@Returns: + + +<!-- ##### FUNCTION g_creat ##### --> +<para> + +</para> + +@filename: +@mode: +@Returns: + + diff --git a/docs/reference/glib/tmpl/glib-unused.sgml b/docs/reference/glib/tmpl/glib-unused.sgml index 6cd8c10d0..b089e6686 100644 --- a/docs/reference/glib/tmpl/glib-unused.sgml +++ b/docs/reference/glib/tmpl/glib-unused.sgml @@ -44,6 +44,10 @@ serializes and deserializes a desktop entry. Desktop Entry Parser +<!-- ##### SECTION ./tmpl/glib-unused.sgml:Stability_Level ##### --> + + + <!-- ##### ENUM GChannelError ##### --> <para> @@ -629,6 +633,17 @@ in any UNIX manual. @error: @Returns: +<!-- ##### FUNCTION g_file_replace ##### --> +<para> + +</para> + +@filename: +@contents: +@length: +@error: +@Returns: + <!-- ##### FUNCTION g_io_channel_error_quark ##### --> <para> diff --git a/docs/reference/glib/tmpl/hash_tables.sgml b/docs/reference/glib/tmpl/hash_tables.sgml index 339e80770..f1798f93a 100644 --- a/docs/reference/glib/tmpl/hash_tables.sgml +++ b/docs/reference/glib/tmpl/hash_tables.sgml @@ -331,14 +331,14 @@ This function is deprecated and will be removed in the next major @v1: @v2: -@Returns: +@Returns: <!-- ##### FUNCTION g_str_hash ##### --> <para> </para> -@v: -@Returns: +@v: +@Returns: diff --git a/docs/reference/glib/tmpl/hooks.sgml b/docs/reference/glib/tmpl/hooks.sgml index 14ea223f1..666e6d79b 100644 --- a/docs/reference/glib/tmpl/hooks.sgml +++ b/docs/reference/glib/tmpl/hooks.sgml @@ -17,6 +17,9 @@ and the list of hook functions can be invoked. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GHookList ##### --> <para> The <structname>GHookList</structname> struct represents a diff --git a/docs/reference/glib/tmpl/i18n.sgml b/docs/reference/glib/tmpl/i18n.sgml index fc34eb133..391ea95ab 100644 --- a/docs/reference/glib/tmpl/i18n.sgml +++ b/docs/reference/glib/tmpl/i18n.sgml @@ -27,6 +27,9 @@ the GETTEXT_PACKAGE macro suitably for your library: The gettext manual. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### MACRO _ ##### --> <para> Marks a string for translation, gets replaced with the translated string diff --git a/docs/reference/glib/tmpl/iochannels.sgml b/docs/reference/glib/tmpl/iochannels.sgml index 7ae3245ee..57219fcac 100644 --- a/docs/reference/glib/tmpl/iochannels.sgml +++ b/docs/reference/glib/tmpl/iochannels.sgml @@ -64,6 +64,9 @@ Convenience functions for creating #GIOChannel instances and adding them to the </variablelist> </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GIOChannel ##### --> <para> A data structure representing an IO Channel. The fields should be considered diff --git a/docs/reference/glib/tmpl/keyfile.sgml b/docs/reference/glib/tmpl/keyfile.sgml index bd5a3c84e..18f396916 100644 --- a/docs/reference/glib/tmpl/keyfile.sgml +++ b/docs/reference/glib/tmpl/keyfile.sgml @@ -97,6 +97,9 @@ Key and Group names are case-sensitive, for example a group called </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GKeyFile ##### --> <para> The <structname>GKeyFile</structname> struct contains only private fields diff --git a/docs/reference/glib/tmpl/limits.sgml b/docs/reference/glib/tmpl/limits.sgml index 44d28a6bc..038b5b404 100644 --- a/docs/reference/glib/tmpl/limits.sgml +++ b/docs/reference/glib/tmpl/limits.sgml @@ -15,6 +15,9 @@ the standard integer and floating point types. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### MACRO G_MININT ##### --> <para> The minimum value which can be held in a #gint. diff --git a/docs/reference/glib/tmpl/linked_lists_double.sgml b/docs/reference/glib/tmpl/linked_lists_double.sgml index 28902757a..f0398bb1c 100644 --- a/docs/reference/glib/tmpl/linked_lists_double.sgml +++ b/docs/reference/glib/tmpl/linked_lists_double.sgml @@ -64,6 +64,9 @@ To free the entire list, use g_list_free(). </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GList ##### --> <para> The #GList struct is used for each element in a doubly-linked list. diff --git a/docs/reference/glib/tmpl/linked_lists_single.sgml b/docs/reference/glib/tmpl/linked_lists_single.sgml index 17a004cbf..64b7cf705 100644 --- a/docs/reference/glib/tmpl/linked_lists_single.sgml +++ b/docs/reference/glib/tmpl/linked_lists_single.sgml @@ -64,6 +64,9 @@ To free the entire list, use g_slist_free(). </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GSList ##### --> <para> The #GSList struct is used for each element in the singly-linked list. @@ -74,7 +77,6 @@ The #GSList struct is used for each element in the singly-linked list. <link linkend="glib-Type-Conversion-Macros">Type Conversion Macros</link>. @next: contains the link to the next element in the list. - <!-- ##### FUNCTION g_slist_alloc ##### --> <para> Allocates space for one #GSList element. diff --git a/docs/reference/glib/tmpl/macros.sgml b/docs/reference/glib/tmpl/macros.sgml index 131bc02fa..e453ed2f5 100644 --- a/docs/reference/glib/tmpl/macros.sgml +++ b/docs/reference/glib/tmpl/macros.sgml @@ -14,6 +14,9 @@ These macros provide a few commonly-used features. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### MACRO G_OS_WIN32 ##### --> <para> This macro is defined only on Windows. So you can bracket diff --git a/docs/reference/glib/tmpl/macros_misc.sgml b/docs/reference/glib/tmpl/macros_misc.sgml index eacb95dba..0d070d775 100644 --- a/docs/reference/glib/tmpl/macros_misc.sgml +++ b/docs/reference/glib/tmpl/macros_misc.sgml @@ -15,6 +15,9 @@ by application programmers. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### MACRO G_INLINE_FUNC ##### --> <para> Used to declare inline functions. If inline functions are not supported on @@ -238,6 +241,8 @@ See the GNU C documentation for details. Since: 2.8 + + <!-- ##### MACRO G_GNUC_FUNCTION ##### --> <para> Expands to the GNU C <literal>__FUNCTION__</literal> variable if the diff --git a/docs/reference/glib/tmpl/main.sgml b/docs/reference/glib/tmpl/main.sgml index d9a8e3454..38b352216 100644 --- a/docs/reference/glib/tmpl/main.sgml +++ b/docs/reference/glib/tmpl/main.sgml @@ -101,6 +101,9 @@ manages all available sources of events. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GMainLoop ##### --> <para> The <structname>GMainLoop</structname> struct is an opaque data type diff --git a/docs/reference/glib/tmpl/markup.sgml b/docs/reference/glib/tmpl/markup.sgml index c795ee513..76abdda5d 100644 --- a/docs/reference/glib/tmpl/markup.sgml +++ b/docs/reference/glib/tmpl/markup.sgml @@ -85,6 +85,9 @@ Sections marked as CDATA </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### ENUM GMarkupError ##### --> <para> Error codes returned by markup parsing. diff --git a/docs/reference/glib/tmpl/memory.sgml b/docs/reference/glib/tmpl/memory.sgml index 7c5f8f4e1..063b7a949 100644 --- a/docs/reference/glib/tmpl/memory.sgml +++ b/docs/reference/glib/tmpl/memory.sgml @@ -20,6 +20,9 @@ This also means that there is no need to check if the call succeeded. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### MACRO g_new ##### --> <para> Allocates @n_structs elements of type @struct_type. @@ -228,18 +231,12 @@ Wraps g_alloca() in a more typesafe manner. <!-- ##### MACRO g_memmove ##### --> <para> -Copies a block of memory @n bytes long, from @s to @d. -The source and destination areas may overlap. -</para> -<para> -In order to use this function, you must include <filename>string.h</filename> -yourself, because this macro will typically simply resolve -to <function>memmove()</function> and GLib does not include <filename>string.h</filename> for you. + </para> -@d: the destination address to copy the bytes to. -@s: the source address to copy the bytes from. -@n: the number of bytes to copy. +@dest: +@src: +@len: <!-- ##### FUNCTION g_memdup ##### --> diff --git a/docs/reference/glib/tmpl/memory_chunks.sgml b/docs/reference/glib/tmpl/memory_chunks.sgml index 2fbe0c0ac..519904d61 100644 --- a/docs/reference/glib/tmpl/memory_chunks.sgml +++ b/docs/reference/glib/tmpl/memory_chunks.sgml @@ -122,6 +122,9 @@ To help debug memory chunks, use g_mem_chunk_info() and g_mem_chunk_print(). </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GMemChunk ##### --> <para> The #GMemChunk struct is an opaque data structure representing a memory diff --git a/docs/reference/glib/tmpl/messages.sgml b/docs/reference/glib/tmpl/messages.sgml index 4e04bfc1b..3854f3002 100644 --- a/docs/reference/glib/tmpl/messages.sgml +++ b/docs/reference/glib/tmpl/messages.sgml @@ -20,6 +20,9 @@ These can be extended with user-defined levels. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### MACRO G_LOG_DOMAIN ##### --> <para> Defines the log domain. diff --git a/docs/reference/glib/tmpl/misc_utils.sgml b/docs/reference/glib/tmpl/misc_utils.sgml index bea827583..eb32d3bce 100644 --- a/docs/reference/glib/tmpl/misc_utils.sgml +++ b/docs/reference/glib/tmpl/misc_utils.sgml @@ -14,6 +14,9 @@ These are portable utility functions. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### FUNCTION g_get_application_name ##### --> <para> @@ -74,12 +77,20 @@ These are portable utility functions. @variable: +<!-- ##### FUNCTION g_listenv ##### --> +<para> + +</para> + +@Returns: + + <!-- ##### FUNCTION g_get_user_name ##### --> <para> </para> -@Returns: +@Returns: <!-- ##### FUNCTION g_get_real_name ##### --> @@ -87,7 +98,7 @@ These are portable utility functions. </para> -@Returns: +@Returns: <!-- ##### FUNCTION g_get_user_cache_dir ##### --> @@ -151,7 +162,7 @@ These are portable utility functions. </para> -@Returns: +@Returns: <!-- ##### FUNCTION g_basename ##### --> @@ -181,8 +192,8 @@ The returned string should be freed when no longer needed. </para> -@file_name: -@Returns: +@file_name: +@Returns: <!-- ##### FUNCTION g_path_skip_root ##### --> @@ -309,8 +320,8 @@ larger than @num. @string: @keys: -@nkeys: -@Returns: +@nkeys: +@Returns: <!-- ##### STRUCT GDebugKey ##### --> diff --git a/docs/reference/glib/tmpl/modules.sgml b/docs/reference/glib/tmpl/modules.sgml index db2e00070..0364423b5 100644 --- a/docs/reference/glib/tmpl/modules.sgml +++ b/docs/reference/glib/tmpl/modules.sgml @@ -88,6 +88,9 @@ just_say_hello (const char *filename, GError **error) </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GModule ##### --> <para> The #GModule struct is an opaque data structure to represent a diff --git a/docs/reference/glib/tmpl/numerical.sgml b/docs/reference/glib/tmpl/numerical.sgml index 1466dd385..d9c5ac24c 100644 --- a/docs/reference/glib/tmpl/numerical.sgml +++ b/docs/reference/glib/tmpl/numerical.sgml @@ -24,6 +24,9 @@ The #GFloatIEEE754 and #GDoubleIEEE754 unions are used to access the <ulink url="http://cch.loria.fr/documentation/IEEE754/numerical_comp_guide/ncg_math.doc.html">http://cch.loria.fr/documentation/IEEE754/numerical_comp_guide/ncg_math.doc.html</ulink> </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### MACRO G_IEEE754_FLOAT_BIAS ##### --> <para> See <ulink url="http://cch.loria.fr/documentation/IEEE754/numerical_comp_guide/ncg_math.doc.html">http://cch.loria.fr/documentation/IEEE754/numerical_comp_guide/ncg_math.doc.html</ulink> diff --git a/docs/reference/glib/tmpl/option.sgml b/docs/reference/glib/tmpl/option.sgml index 7363cb00b..3aa2c1b46 100644 --- a/docs/reference/glib/tmpl/option.sgml +++ b/docs/reference/glib/tmpl/option.sgml @@ -124,6 +124,9 @@ main (int argc, char *argv[]) </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### ENUM GOptionError ##### --> <para> Error codes returned by option parsing. diff --git a/docs/reference/glib/tmpl/patterns.sgml b/docs/reference/glib/tmpl/patterns.sgml index bcaf12d13..48d6661fd 100644 --- a/docs/reference/glib/tmpl/patterns.sgml +++ b/docs/reference/glib/tmpl/patterns.sgml @@ -30,6 +30,9 @@ pattern compilation. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GPatternSpec ##### --> <para> A <structname>GPatternSpec</structname> is the 'compiled' form of a pattern. diff --git a/docs/reference/glib/tmpl/quarks.sgml b/docs/reference/glib/tmpl/quarks.sgml index 9a531f3d8..7a8159edf 100644 --- a/docs/reference/glib/tmpl/quarks.sgml +++ b/docs/reference/glib/tmpl/quarks.sgml @@ -31,6 +31,9 @@ To find the #GQuark corresponding to a given string, use g_quark_try_string(). </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### TYPEDEF GQuark ##### --> <para> A GQuark is an integer which uniquely identifies a particular string. diff --git a/docs/reference/glib/tmpl/queue.sgml b/docs/reference/glib/tmpl/queue.sgml index 6b5e8689d..44e262091 100644 --- a/docs/reference/glib/tmpl/queue.sgml +++ b/docs/reference/glib/tmpl/queue.sgml @@ -35,6 +35,9 @@ To free the entire queue, use g_queue_free(). </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GQueue ##### --> <para> Contains the public fields of a <link linkend="glib-queues">Queue</link>. diff --git a/docs/reference/glib/tmpl/random_numbers.sgml b/docs/reference/glib/tmpl/random_numbers.sgml index 1dbdc61c9..947897ef0 100644 --- a/docs/reference/glib/tmpl/random_numbers.sgml +++ b/docs/reference/glib/tmpl/random_numbers.sgml @@ -55,6 +55,9 @@ with Glib-2.0 that you need to reproduce exactly. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GRand ##### --> <para> The #GRand struct is an opaque data structure. It should only be diff --git a/docs/reference/glib/tmpl/relations.sgml b/docs/reference/glib/tmpl/relations.sgml index 102f0fb41..3b34fc188 100644 --- a/docs/reference/glib/tmpl/relations.sgml +++ b/docs/reference/glib/tmpl/relations.sgml @@ -56,6 +56,9 @@ To help debug #GRelation objects, use g_relation_print(). </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GRelation ##### --> <para> The #GRelation struct is an opaque data structure to represent a diff --git a/docs/reference/glib/tmpl/scanner.sgml b/docs/reference/glib/tmpl/scanner.sgml index bac9d601a..494b1d278 100644 --- a/docs/reference/glib/tmpl/scanner.sgml +++ b/docs/reference/glib/tmpl/scanner.sgml @@ -19,6 +19,9 @@ understand it myself. Look at gtkrc.c for some code using the scanner. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GScanner ##### --> <para> The data structure representing a lexical scanner. diff --git a/docs/reference/glib/tmpl/shell.sgml b/docs/reference/glib/tmpl/shell.sgml index 399aa4f57..b2304e639 100644 --- a/docs/reference/glib/tmpl/shell.sgml +++ b/docs/reference/glib/tmpl/shell.sgml @@ -14,6 +14,9 @@ shell-like commandline handling. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### ENUM GShellError ##### --> <para> Error codes returned by shell functions. diff --git a/docs/reference/glib/tmpl/spawn.sgml b/docs/reference/glib/tmpl/spawn.sgml index 36615b444..871433696 100644 --- a/docs/reference/glib/tmpl/spawn.sgml +++ b/docs/reference/glib/tmpl/spawn.sgml @@ -14,6 +14,9 @@ process launching with <function>fork()</function>/<function>exec()</function>. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### ENUM GSpawnError ##### --> <para> Error codes returned by spawning processes. diff --git a/docs/reference/glib/tmpl/string_chunks.sgml b/docs/reference/glib/tmpl/string_chunks.sgml index 4b5fcba0c..d6fa6a780 100644 --- a/docs/reference/glib/tmpl/string_chunks.sgml +++ b/docs/reference/glib/tmpl/string_chunks.sgml @@ -40,6 +40,9 @@ It is not possible to free individual strings. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GStringChunk ##### --> <para> An opaque data structure representing String Chunks. diff --git a/docs/reference/glib/tmpl/string_utils.sgml b/docs/reference/glib/tmpl/string_utils.sgml index a772d9584..0fce6c4de 100644 --- a/docs/reference/glib/tmpl/string_utils.sgml +++ b/docs/reference/glib/tmpl/string_utils.sgml @@ -37,6 +37,9 @@ wide characters (see g_unichar_iswide()) into account. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### FUNCTION g_strdup ##### --> <para> Duplicates a string. diff --git a/docs/reference/glib/tmpl/strings.sgml b/docs/reference/glib/tmpl/strings.sgml index 24fa7edb4..fb68ae17f 100644 --- a/docs/reference/glib/tmpl/strings.sgml +++ b/docs/reference/glib/tmpl/strings.sgml @@ -76,7 +76,7 @@ you do not have to worry about having enough space to copy the string. </para> @string: the destination #GString. Its current contents are destroyed. -@rval: the string to copy into @string +@rval: the string to copy into @string @Returns: the destination #GString. <!-- # Unused Parameters # --> @val: the string to copy into @string. diff --git a/docs/reference/glib/tmpl/thread_pools.sgml b/docs/reference/glib/tmpl/thread_pools.sgml index a13629a3e..1ce7446a7 100644 --- a/docs/reference/glib/tmpl/thread_pools.sgml +++ b/docs/reference/glib/tmpl/thread_pools.sgml @@ -59,6 +59,9 @@ can be stopped by calling g_thread_pool_stop_unused_threads(). </variablelist> </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GThreadPool ##### --> <para> The #GThreadPool struct represents a thread pool. It has six public diff --git a/docs/reference/glib/tmpl/threads.sgml b/docs/reference/glib/tmpl/threads.sgml index 72104c40f..e84bb98c5 100644 --- a/docs/reference/glib/tmpl/threads.sgml +++ b/docs/reference/glib/tmpl/threads.sgml @@ -49,6 +49,9 @@ primitives to portably create and manage threads (#GThread). </variablelist> </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### MACRO G_THREADS_ENABLED ##### --> <para> diff --git a/docs/reference/glib/tmpl/timers.sgml b/docs/reference/glib/tmpl/timers.sgml index 59dacc5cc..d361c9fed 100644 --- a/docs/reference/glib/tmpl/timers.sgml +++ b/docs/reference/glib/tmpl/timers.sgml @@ -17,6 +17,9 @@ get exactly right, so #GTimer provides a portable/convenient interface. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GTimer ##### --> <para> Opaque datatype that records a start time. diff --git a/docs/reference/glib/tmpl/trash_stack.sgml b/docs/reference/glib/tmpl/trash_stack.sgml index d91bf4ceb..ac1fa3844 100644 --- a/docs/reference/glib/tmpl/trash_stack.sgml +++ b/docs/reference/glib/tmpl/trash_stack.sgml @@ -21,6 +21,9 @@ is a perfectly valid empty stack. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GTrashStack ##### --> <para> Each piece of memory that is pushed onto the stack diff --git a/docs/reference/glib/tmpl/trees-binary.sgml b/docs/reference/glib/tmpl/trees-binary.sgml index d3838a86f..36db07216 100644 --- a/docs/reference/glib/tmpl/trees-binary.sgml +++ b/docs/reference/glib/tmpl/trees-binary.sgml @@ -40,6 +40,9 @@ To destroy a #GTree, use g_tree_destroy(). </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GTree ##### --> <para> The <structname>GTree</structname> struct is an opaque data structure representing a diff --git a/docs/reference/glib/tmpl/trees-nary.sgml b/docs/reference/glib/tmpl/trees-nary.sgml index 6259925af..3cdbc436f 100644 --- a/docs/reference/glib/tmpl/trees-nary.sgml +++ b/docs/reference/glib/tmpl/trees-nary.sgml @@ -49,6 +49,9 @@ g_node_destroy(). </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GNode ##### --> <para> The <structname>GNode</structname> struct represents one node in a diff --git a/docs/reference/glib/tmpl/type_conversion.sgml b/docs/reference/glib/tmpl/type_conversion.sgml index 41527e5cb..6d204e5be 100644 --- a/docs/reference/glib/tmpl/type_conversion.sgml +++ b/docs/reference/glib/tmpl/type_conversion.sgml @@ -55,6 +55,9 @@ integer; values outside the range of a 32-bit integer will be mangled. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### MACRO GINT_TO_POINTER ##### --> <para> Stuffs an integer into a pointer type. diff --git a/docs/reference/glib/tmpl/types.sgml b/docs/reference/glib/tmpl/types.sgml index d9eec4445..f618a34d1 100644 --- a/docs/reference/glib/tmpl/types.sgml +++ b/docs/reference/glib/tmpl/types.sgml @@ -37,6 +37,9 @@ for completeness - #gchar, #gint, #gshort, #glong, #gfloat, #gdouble. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### TYPEDEF gboolean ##### --> <para> A standard <type>boolean</type> type. diff --git a/docs/reference/glib/tmpl/unicode.sgml b/docs/reference/glib/tmpl/unicode.sgml index 1f197ddb2..994297f2b 100644 --- a/docs/reference/glib/tmpl/unicode.sgml +++ b/docs/reference/glib/tmpl/unicode.sgml @@ -29,6 +29,9 @@ Convenience functions for converting between UTF-8 and the locale encoding. </variablelist> </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### TYPEDEF gunichar ##### --> <para> A type which can hold any UCS-4 character code. diff --git a/docs/reference/glib/tmpl/version.sgml b/docs/reference/glib/tmpl/version.sgml index 0a2feda13..f46c1e1a5 100644 --- a/docs/reference/glib/tmpl/version.sgml +++ b/docs/reference/glib/tmpl/version.sgml @@ -16,6 +16,9 @@ typically use the features described here. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### VARIABLE glib_major_version ##### --> <para> The major version number of the GLib library. diff --git a/docs/reference/glib/tmpl/warnings.sgml b/docs/reference/glib/tmpl/warnings.sgml index 2bc97171f..9db10dacf 100644 --- a/docs/reference/glib/tmpl/warnings.sgml +++ b/docs/reference/glib/tmpl/warnings.sgml @@ -14,6 +14,9 @@ These functions provide support for outputting messages. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### FUNCTION g_print ##### --> <para> Outputs a formatted message via the print handler. diff --git a/docs/reference/gobject/gobject-sections.txt b/docs/reference/gobject/gobject-sections.txt index f42e01c2b..dc4917c4d 100644 --- a/docs/reference/gobject/gobject-sections.txt +++ b/docs/reference/gobject/gobject-sections.txt @@ -242,6 +242,9 @@ g_object_weak_ref g_object_weak_unref g_object_add_weak_pointer g_object_remove_weak_pointer +GToggleNotify +g_object_add_toggle_ref +g_object_remove_toggle_ref g_object_connect g_object_disconnect g_object_set diff --git a/docs/reference/gobject/tmpl/gboxed.sgml b/docs/reference/gobject/tmpl/gboxed.sgml index 84aeb7f58..fd178e253 100644 --- a/docs/reference/gobject/tmpl/gboxed.sgml +++ b/docs/reference/gobject/tmpl/gboxed.sgml @@ -14,6 +14,9 @@ A mechanism to wrap opaque C structures registered by the type system #GParamSpecBoxed, g_param_spec_boxed() </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### USER_FUNCTION GBoxedCopyFunc ##### --> <para> This function is provided by the user and should produce a copy of the passed diff --git a/docs/reference/gobject/tmpl/gclosure.sgml b/docs/reference/gobject/tmpl/gclosure.sgml index d4e2e413e..3c9d80ada 100644 --- a/docs/reference/gobject/tmpl/gclosure.sgml +++ b/docs/reference/gobject/tmpl/gclosure.sgml @@ -60,6 +60,9 @@ automatically removed when the objects they point to go away. </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### MACRO G_CLOSURE_NEEDS_MARSHAL ##### --> <para> Returns %TRUE if a #GClosureMarshal marshaller has not yet been set on diff --git a/docs/reference/gobject/tmpl/gparamspec.sgml b/docs/reference/gobject/tmpl/gparamspec.sgml index 167ebc1a8..18f63bf0e 100644 --- a/docs/reference/gobject/tmpl/gparamspec.sgml +++ b/docs/reference/gobject/tmpl/gparamspec.sgml @@ -21,6 +21,9 @@ g_object_class_install_property(), g_object_set(), g_object_get(), g_object_set_property(), g_object_get_property(), g_value_register_transform_func() </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### MACRO G_TYPE_IS_PARAM ##### --> <para> Returns whether @type "is a" %G_TYPE_PARAM. diff --git a/docs/reference/gobject/tmpl/gtypeplugin.sgml b/docs/reference/gobject/tmpl/gtypeplugin.sgml index d33914832..07b535f7e 100644 --- a/docs/reference/gobject/tmpl/gtypeplugin.sgml +++ b/docs/reference/gobject/tmpl/gtypeplugin.sgml @@ -70,6 +70,9 @@ handles multiple registered types per module. #GTypeModule and g_type_register_dynamic(). </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GTypePlugin ##### --> <para> The <structname>GTypePlugin</structname> typedef is used as a placeholder diff --git a/docs/reference/gobject/tmpl/objects.sgml b/docs/reference/gobject/tmpl/objects.sgml index 0f3f4cc32..3ac2f9dd2 100644 --- a/docs/reference/gobject/tmpl/objects.sgml +++ b/docs/reference/gobject/tmpl/objects.sgml @@ -14,6 +14,9 @@ The base object type </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### STRUCT GObject ##### --> <para> All the fields in the <structname>GObject</structname> structure are private @@ -432,6 +435,76 @@ to match the one used with g_object_add_weak_pointer(). @weak_pointer_location: The memory address of a pointer. +<!-- ##### USER_FUNCTION GToggleNotify ##### --> +<para> +A callback function used for notification when the state +of a toggle reference changes. See g_object_add_toggle_ref(). +</para> + +@data: Callback data passed to g_object_add_toggle_ref() +@object: The object on which g_object_add_toggle_ref() was called. +@is_last_ref: %TRUE if the toggle reference is now the + last reference to the object. %FALSE if the toggle + reference was the last reference and there are now other + references. + + +<!-- ##### FUNCTION g_object_add_toggle_ref ##### --> +<para> +Increases the reference count of the object by one and sets a +callback to be called when all other references to the object are +dropped, or when this is already the last reference to the object +and another reference is established. +</para> +<para> +This functionality is intended for binding @object to a proxy +object managed by another memory manager. This is done with two +paired references: the strong reference added by +g_object_add_toggle_ref() and a reverse reference to the proxy +object which is either a strong reference or weak reference. +</para> +<para> +The setup is that when there are no other references to @object, +only a weak reference is held in the reverse direction from @object +to the proxy object, but when there are other references held to +@object, a strong reference is held. The @notify callback is called +when the reference from @object to the proxy object should be +<firstterm>toggled</firstterm> from strong to weak (@is_last_ref +true) or weak to strong (@is_last_ref false). +</para> +<para> +Since a (normal) reference must be held to the object before +calling g_object_toggle_ref(), the initial state of the reverse +link is always strong. +</para> +<para> +Multiple toggle references may be added to the same gobject, +however if there are multiple toggle references to an object, none +of them will ever be notified until all but one are removed. For +this reason, you should only ever use a toggle reference if there +is important state in the proxy object. +</para> + +@object: a #GObject +@notify: a function to call when this reference is the + last reference to the object, or is no longer + the last reference. +@data: data to pass to @notify + + +<!-- ##### FUNCTION g_object_remove_toggle_ref ##### --> +<para> +Removes a reference added with g_object_add_toggle_ref(). The +reference count of the object is decreased by one. +</para> + +@object: a #GObject +@notify: a function to call when this reference is the + last reference to the object, or is no longer + the last reference. +@data: data to pass to @notify + + <!-- ##### FUNCTION g_object_connect ##### --> <para> A convenience function to connect multiple signals at once. diff --git a/docs/reference/gobject/tmpl/param_value_types.sgml b/docs/reference/gobject/tmpl/param_value_types.sgml index 1fb32ec6a..f5bd46c10 100644 --- a/docs/reference/gobject/tmpl/param_value_types.sgml +++ b/docs/reference/gobject/tmpl/param_value_types.sgml @@ -833,7 +833,6 @@ A #GParamSpec derived structure that contains the meta data for double propertie @default_value: default value for the property specified @epsilon: values closer than @epsilon will be considered identical by g_param_values_cmp(); the default value is 1e-90. - <!-- ##### FUNCTION g_param_spec_double ##### --> <para> diff --git a/docs/reference/gobject/tmpl/value_collection.sgml b/docs/reference/gobject/tmpl/value_collection.sgml index e33b48627..2f7ec68f6 100644 --- a/docs/reference/gobject/tmpl/value_collection.sgml +++ b/docs/reference/gobject/tmpl/value_collection.sgml @@ -14,6 +14,9 @@ Converting varargs to generic values </para> +<!-- ##### SECTION Stability_Level ##### --> + + <!-- ##### UNION GTypeCValue ##### --> <para> A union holding one collected value. diff --git a/glib/Makefile.am b/glib/Makefile.am index de504e278..527cf3cf1 100644 --- a/glib/Makefile.am +++ b/glib/Makefile.am @@ -70,6 +70,7 @@ libglib_2_0_la_SOURCES = \ gcompletion.c \ gconvert.c \ gdataset.c \ + gdatasetprivate.h \ gdate.c \ gdir.c \ gerror.c \ diff --git a/glib/gdataset.c b/glib/gdataset.c index fbd9c2da4..43580e46a 100644 --- a/glib/gdataset.c +++ b/glib/gdataset.c @@ -37,6 +37,7 @@ #include "glib.h" #include "galias.h" +#include "gdatasetprivate.h" /* --- defines --- */ @@ -91,7 +92,6 @@ static GHashTable *g_quark_ht = NULL; static gchar **g_quarks = NULL; static GQuark g_quark_seq_id = 0; - /* --- functions --- */ /* HOLDS: g_dataset_global_lock */ @@ -102,8 +102,8 @@ g_datalist_clear_i (GData **datalist) /* unlink *all* items before walking their destructors */ - list = *datalist; - *datalist = NULL; + list = G_DATALIST_GET_POINTER (datalist); + G_DATALIST_SET_POINTER (datalist, NULL); while (list) { @@ -139,7 +139,7 @@ g_datalist_clear (GData **datalist) if (!g_dataset_location_ht) g_data_initialize (); - while (*datalist) + while (G_DATALIST_GET_POINTER (datalist)) g_datalist_clear_i (datalist); G_UNLOCK (g_dataset_global); } @@ -210,7 +210,7 @@ g_data_set_internal (GData **datalist, { register GData *list; - list = *datalist; + list = G_DATALIST_GET_POINTER (datalist); if (!data) { register GData *prev; @@ -226,12 +226,12 @@ g_data_set_internal (GData **datalist, prev->next = list->next; else { - *datalist = list->next; + G_DATALIST_SET_POINTER (datalist, list->next); /* the dataset destruction *must* be done * prior to invokation of the data destroy function */ - if (!*datalist && dataset) + if (!list->next && dataset) g_dataset_destroy_internal (dataset); } @@ -309,11 +309,11 @@ g_data_set_internal (GData **datalist, } else list = g_chunk_new (GData, g_data_mem_chunk); - list->next = *datalist; + list->next = G_DATALIST_GET_POINTER (datalist); list->id = key_id; list->data = data; list->destroy_func = destroy_func; - *datalist = list; + G_DATALIST_SET_POINTER (datalist, list); } return NULL; @@ -459,7 +459,7 @@ g_datalist_id_get_data (GData **datalist, { register GData *list; - for (list = *datalist; list; list = list->next) + for (list = G_DATALIST_GET_POINTER (datalist); list; list = list->next) if (list->id == key_id) return list->data; } @@ -509,7 +509,7 @@ g_datalist_foreach (GData **datalist, g_return_if_fail (datalist != NULL); g_return_if_fail (func != NULL); - for (list = *datalist; list; list = next) + for (list = G_DATALIST_GET_POINTER (datalist); list; list = next) { next = list->next; func (list->id, list->data, user_data); @@ -524,6 +524,70 @@ g_datalist_init (GData **datalist) *datalist = NULL; } +/** + * g_datalist_set_flags: + * @datalist: pointer to the location that holds a list + * @flags: the flags to turn on. The values of the flags are + * restricted by %G_DATALIST_FLAGS_MASK (currently + * 3; giving two possible boolean flags). + * A value for @flags that doesn't fit within the mask is + * an error. + * + * Turns on flag values for a data list. This function is used + * to keep a small number of boolean flags in an object with + * a data list without using any additional space. It is + * not generally useful except in circumstances where space + * is very tight. (It is used in the base #GObject type, for + * example.) + **/ +void +g_datalist_set_flags (GData **datalist, + guint flags) +{ + g_return_if_fail (datalist != NULL); + g_return_if_fail ((flags & ~G_DATALIST_FLAGS_MASK) == 0); + + G_DATALIST_SET_FLAGS (datalist, flags); +} + +/** + * g_datalist_unset_flags: + * @datalist: pointer to the location that holds a list + * @flags: the flags to turn off. The values of the flags are + * restricted by %G_DATALIST_FLAGS_MASK (currently + * 3: giving two possible boolean flags). + * A value for @flags that doesn't fit within the mask is + * an error. + * + * Turns off flag values for a data list. See g_datalist_unset_flags() + **/ +void +g_datalist_unset_flags (GData **datalist, + guint flags) +{ + g_return_if_fail (datalist != NULL); + g_return_if_fail ((flags & ~G_DATALIST_FLAGS_MASK) == 0); + + G_DATALIST_UNSET_FLAGS (datalist, flags); +} + +/** + * g_datalist_get_flags: + * @datalist: pointer to the location that holds a list + * + * Gets flags values packed in together with the datalist. + * See g_datalist_set_flags(). + * + * Return value: the flags of the datalist + **/ +guint +g_datalist_get_flags (GData **datalist) +{ + g_return_val_if_fail (datalist != NULL, 0); + + return G_DATALIST_GET_FLAGS (datalist); +} + /* HOLDS: g_dataset_global_lock */ static void g_data_initialize (void) diff --git a/glib/gdataset.h b/glib/gdataset.h index e04a706c1..0376cac97 100644 --- a/glib/gdataset.h +++ b/glib/gdataset.h @@ -39,19 +39,35 @@ typedef void (*GDataForeachFunc) (GQuark key_id, /* Keyed Data List */ -void g_datalist_init (GData **datalist); -void g_datalist_clear (GData **datalist); -gpointer g_datalist_id_get_data (GData **datalist, - GQuark key_id); -void g_datalist_id_set_data_full (GData **datalist, - GQuark key_id, - gpointer data, - GDestroyNotify destroy_func); -gpointer g_datalist_id_remove_no_notify (GData **datalist, - GQuark key_id); -void g_datalist_foreach (GData **datalist, - GDataForeachFunc func, - gpointer user_data); +void g_datalist_init (GData **datalist); +void g_datalist_clear (GData **datalist); +gpointer g_datalist_id_get_data (GData **datalist, + GQuark key_id); +void g_datalist_id_set_data_full (GData **datalist, + GQuark key_id, + gpointer data, + GDestroyNotify destroy_func); +gpointer g_datalist_id_remove_no_notify (GData **datalist, + GQuark key_id); +void g_datalist_foreach (GData **datalist, + GDataForeachFunc func, + gpointer user_data); + +/** + * G_DATALIST_FLAGS_MASK: + * + * A bitmask that restricts the possible flags passed to + * g_datalist_set_flags(). Passing a flags value where + * flags & ~G_DATALIST_FLAGS_MASK != 0 is an error. + */ +#define G_DATALIST_FLAGS_MASK 0x3 + +void g_datalist_set_flags (GData **datalist, + guint flags); +void g_datalist_unset_flags (GData **datalist, + guint flags); +guint g_datalist_get_flags (GData **datalist); + #define g_datalist_id_set_data(dl, q, d) \ g_datalist_id_set_data_full ((dl), (q), (d), NULL) #define g_datalist_id_remove_data(dl, q) \ diff --git a/glib/gdatasetprivate.h b/glib/gdatasetprivate.h new file mode 100644 index 000000000..1a2e3197a --- /dev/null +++ b/glib/gdatasetprivate.h @@ -0,0 +1,53 @@ +/* GLIB - Library of useful routines for C programming + * gdataset-private.h: Internal macros for accessing dataset values + * Copyright (C) 2005 Red Hat + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __G_DATASETPRIVATE_H__ +#define __G_DATASETPRIVATE_H__ + +#include <glib/gdataset.h> + +G_BEGIN_DECLS + +#define G_DATALIST_GET_FLAGS(datalist) \ + ((gsize)*(datalist) & G_DATALIST_FLAGS_MASK) +#define G_DATALIST_SET_FLAGS(datalist, flags) G_STMT_START { \ + *datalist = (GData *)((flags) | (gsize)*(datalist)); \ +} G_STMT_END +#define G_DATALIST_UNSET_FLAGS(datalist, flags) G_STMT_START { \ + *datalist = (GData *)(~(gsize)(flags) & (gsize)*(datalist)); \ +} G_STMT_END + +#define G_DATALIST_GET_POINTER(datalist) \ + ((GData *)((gsize)*(datalist) & ~(gsize)G_DATALIST_FLAGS_MASK)) +#define G_DATALIST_SET_POINTER(datalist,pointer) G_STMT_START { \ + *(datalist) = (GData *)(G_DATALIST_GET_FLAGS (datalist) | \ + (gsize)pointer); \ +} G_STMT_END + +G_END_DECLS + +#endif /* __G_DATASETPRIVATE_H__ */ diff --git a/glib/gfileutils.c b/glib/gfileutils.c index cf21c061b..d0dd3ce53 100644 --- a/glib/gfileutils.c +++ b/glib/gfileutils.c @@ -1068,7 +1068,7 @@ write_to_temp_file (const gchar *contents, } /** - * g_file_replace: + * g_file_set_contents: * @filename: name of a file to write @contents to, in the GLib file name * encoding * @contents: string to write to the file @@ -1108,10 +1108,10 @@ write_to_temp_file (const gchar *contents, * Since: 2.8 **/ gboolean -g_file_replace (const gchar *filename, - const gchar *contents, - gssize length, - GError **error) +g_file_set_contents (const gchar *filename, + const gchar *contents, + gssize length, + GError **error) { gchar *tmp_filename; gboolean retval; diff --git a/glib/gfileutils.h b/glib/gfileutils.h index 2e82d3f39..7c23cadd3 100644 --- a/glib/gfileutils.h +++ b/glib/gfileutils.h @@ -86,7 +86,7 @@ gboolean g_file_get_contents (const gchar *filename, gchar **contents, gsize *length, GError **error); -gboolean g_file_replace (const gchar *filename, +gboolean g_file_set_contents (const gchar *filename, const gchar *contents, gssize length, GError **error); diff --git a/glib/glib.symbols b/glib/glib.symbols index f08e03455..00831ec46 100644 --- a/glib/glib.symbols +++ b/glib/glib.symbols @@ -152,9 +152,12 @@ g_uri_list_extract_uris G_GNUC_MALLOC #if IN_FILE(__G_DATASET_C__) g_datalist_clear g_datalist_foreach +g_datalist_get_flags g_datalist_id_get_data g_datalist_id_remove_no_notify g_datalist_id_set_data_full +g_datalist_set_flags +g_datalist_unset_flags g_datalist_init g_dataset_destroy g_dataset_foreach @@ -252,7 +255,7 @@ g_build_path G_GNUC_NULL_TERMINATED g_file_error_from_errno g_file_error_quark g_file_get_contents PRIVATE -g_file_replace +g_file_set_contents g_file_open_tmp PRIVATE g_file_test PRIVATE g_file_read_link diff --git a/gobject/ChangeLog b/gobject/ChangeLog index fde059539..90c45e0d5 100644 --- a/gobject/ChangeLog +++ b/gobject/ChangeLog @@ -1,3 +1,11 @@ +2005-05-05 Owen Taylor <otaylor@redhat.com> + + * gobject.[ch] gobject.symbols: Add + g_object_add/remove_toggle_ref() functions to get notification + when a reference count is the last remaining reference; this + enables better memory management for language bindings. + (http://mail.gnome.org/archives/gtk-devel-list/2005-April/msg00095.html) + 2005-04-29 Matthias Clasen <mclasen@redhat.com> * gobject.symbols: diff --git a/gobject/gobject.c b/gobject/gobject.c index 723b65f90..aaf4d54a7 100644 --- a/gobject/gobject.c +++ b/gobject/gobject.c @@ -18,6 +18,7 @@ */ #include "gobject.h" #include "gobjectalias.h" +#include <glib/gdatasetprivate.h> /* * MT safe @@ -39,6 +40,10 @@ #define PARAM_SPEC_PARAM_ID(pspec) ((pspec)->param_id) #define PARAM_SPEC_SET_PARAM_ID(pspec, id) ((pspec)->param_id = (id)) +#define OBJECT_HAS_TOGGLE_REF_FLAG 0x1 +#define OBJECT_HAS_TOGGLE_REF(object) \ + ((G_DATALIST_GET_FLAGS(&(object)->qdata) & OBJECT_HAS_TOGGLE_REF_FLAG) != 0) + /* --- signals --- */ enum { @@ -105,6 +110,7 @@ static void object_interface_check_properties (gpointer func_da /* --- variables --- */ static GQuark quark_closure_array = 0; static GQuark quark_weak_refs = 0; +static GQuark quark_toggle_refs = 0; static GParamSpecPool *pspec_pool = NULL; static GObjectNotifyContext property_notify_context = { 0, }; static gulong gobject_signals[LAST_SIGNAL] = { 0, }; @@ -241,6 +247,7 @@ g_object_do_class_init (GObjectClass *class) quark_closure_array = g_quark_from_static_string ("GObject-closure-array"); quark_weak_refs = g_quark_from_static_string ("GObject-weak-references"); + quark_toggle_refs = g_quark_from_static_string ("GObject-toggle-references"); pspec_pool = g_param_spec_pool_new (TRUE); property_notify_context.quark_notify_queue = g_quark_from_static_string ("GObject-notify-queue"); property_notify_context.dispatcher = g_object_notify_dispatcher; @@ -1519,10 +1526,8 @@ g_object_weak_unref (GObject *object, found_one = TRUE; wstack->n_weak_refs -= 1; if (i != wstack->n_weak_refs) - { - wstack->weak_refs[i].notify = wstack->weak_refs[wstack->n_weak_refs].notify; - wstack->weak_refs[i].data = wstack->weak_refs[wstack->n_weak_refs].data; - } + wstack->weak_refs[i] = wstack->weak_refs[wstack->n_weak_refs]; + break; } } @@ -1554,6 +1559,106 @@ g_object_remove_weak_pointer (GObject *object, weak_pointer_location); } +typedef struct { + GObject *object; + guint n_toggle_refs; + struct { + GToggleNotify notify; + gpointer data; + } toggle_refs[1]; /* flexible array */ +} ToggleRefStack; + +static void +toggle_refs_notify (GObject *object, + gboolean is_last_ref) +{ + ToggleRefStack *tstack = g_datalist_id_get_data (&object->qdata, quark_toggle_refs); + + /* Reentrancy here is not as tricky as it seems, because a toggle reference + * will only be notified when there is exactly one of them. + */ + g_assert (tstack->n_toggle_refs == 1); + tstack->toggle_refs[0].notify (tstack->toggle_refs[0].data, tstack->object, is_last_ref); +} + +void +g_object_add_toggle_ref (GObject *object, + GToggleNotify notify, + gpointer data) +{ + ToggleRefStack *tstack; + guint i; + + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (notify != NULL); + g_return_if_fail (object->ref_count >= 1); + + g_object_ref (object); + + tstack = g_datalist_id_remove_no_notify (&object->qdata, quark_toggle_refs); + if (tstack) + { + i = tstack->n_toggle_refs++; + /* allocate i = tstate->n_toggle_refs - 1 positions beyond the 1 declared + * in tstate->toggle_refs */ + tstack = g_realloc (tstack, sizeof (*tstack) + sizeof (tstack->toggle_refs[0]) * i); + } + else + { + tstack = g_renew (ToggleRefStack, NULL, 1); + tstack->object = object; + tstack->n_toggle_refs = 1; + i = 0; + } + + /* Set a flag for fast lookup after adding the first toggle reference */ + if (tstack->n_toggle_refs == 1) + G_DATALIST_SET_FLAGS (&object->qdata, OBJECT_HAS_TOGGLE_REF_FLAG); + + tstack->toggle_refs[i].notify = notify; + tstack->toggle_refs[i].data = data; + g_datalist_id_set_data_full (&object->qdata, quark_toggle_refs, tstack, + (GDestroyNotify)g_free); +} + +void +g_object_remove_toggle_ref (GObject *object, + GToggleNotify notify, + gpointer data) +{ + ToggleRefStack *tstack; + gboolean found_one = FALSE; + + g_return_if_fail (G_IS_OBJECT (object)); + g_return_if_fail (notify != NULL); + + tstack = g_datalist_id_get_data (&object->qdata, quark_toggle_refs); + if (tstack) + { + guint i; + + for (i = 0; i < tstack->n_toggle_refs; i++) + if (tstack->toggle_refs[i].notify == notify && + tstack->toggle_refs[i].data == data) + { + found_one = TRUE; + tstack->n_toggle_refs -= 1; + if (i != tstack->n_toggle_refs) + tstack->toggle_refs[i] = tstack->toggle_refs[tstack->n_toggle_refs]; + + if (tstack->n_toggle_refs == 0) + G_DATALIST_UNSET_FLAGS (&object->qdata, OBJECT_HAS_TOGGLE_REF_FLAG); + + g_object_unref (object); + + break; + } + } + + if (!found_one) + g_warning ("%s: couldn't find toggle ref %p(%p)", G_STRFUNC, notify, data); +} + gpointer g_object_ref (gpointer _object) { @@ -1568,6 +1673,8 @@ g_object_ref (gpointer _object) #endif /* G_ENABLE_DEBUG */ object->ref_count += 1; + if (object->ref_count == 2 && OBJECT_HAS_TOGGLE_REF (object)) + toggle_refs_notify (object, FALSE); return object; } @@ -1586,7 +1693,11 @@ g_object_unref (gpointer _object) #endif /* G_ENABLE_DEBUG */ if (object->ref_count > 1) - object->ref_count -= 1; + { + object->ref_count -= 1; + if (object->ref_count == 1 && OBJECT_HAS_TOGGLE_REF (object)) + toggle_refs_notify (object, TRUE); + } else g_object_last_unref (object); } diff --git a/gobject/gobject.h b/gobject/gobject.h index f3935ca9e..e835e7348 100644 --- a/gobject/gobject.h +++ b/gobject/gobject.h @@ -178,6 +178,18 @@ void g_object_add_weak_pointer (GObject *object, gpointer *weak_pointer_location); void g_object_remove_weak_pointer (GObject *object, gpointer *weak_pointer_location); + +typedef void (*GToggleNotify) (gpointer data, + GObject *object, + gboolean is_last_ref); + +void g_object_add_toggle_ref (GObject *object, + GToggleNotify notify, + gpointer data); +void g_object_remove_toggle_ref (GObject *object, + GToggleNotify notify, + gpointer data); + gpointer g_object_get_qdata (GObject *object, GQuark quark); void g_object_set_qdata (GObject *object, diff --git a/gobject/gobject.symbols b/gobject/gobject.symbols index 7b32ea15a..9af8c9a96 100644 --- a/gobject/gobject.symbols +++ b/gobject/gobject.symbols @@ -148,6 +148,8 @@ g_object_unref g_object_watch_closure g_object_weak_ref g_object_weak_unref +g_object_add_toggle_ref +g_object_remove_toggle_ref g_value_get_object g_value_set_object g_value_dup_object diff --git a/tests/gobject/Makefile.am b/tests/gobject/Makefile.am index b09d4de62..778b53554 100644 --- a/tests/gobject/Makefile.am +++ b/tests/gobject/Makefile.am @@ -52,7 +52,8 @@ test_programs = \ ifaceinit \ ifaceinherit \ ifaceproperties \ - override + override \ + references check_PROGRAMS = $(test_programs) diff --git a/tests/gobject/references.c b/tests/gobject/references.c new file mode 100644 index 000000000..86c700f09 --- /dev/null +++ b/tests/gobject/references.c @@ -0,0 +1,281 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2005 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#undef G_LOG_DOMAIN +#define G_LOG_DOMAIN "TestReferences" + +#undef G_DISABLE_ASSERT +#undef G_DISABLE_CHECKS +#undef G_DISABLE_CAST_CHECKS + +#include <glib-object.h> + +/* This test tests weak and toggle references + */ + +static GObject *global_object; + +static gboolean object_destroyed; +static gboolean weak_ref1_notified; +static gboolean weak_ref2_notified; +static gboolean toggle_ref1_weakened; +static gboolean toggle_ref1_strengthened; +static gboolean toggle_ref2_weakened; +static gboolean toggle_ref2_strengthened; +static gboolean toggle_ref3_weakened; +static gboolean toggle_ref3_strengthened; + +/* + * TestObject, a parent class for TestObject + */ +#define TEST_TYPE_OBJECT (test_object_get_type ()) +typedef struct _TestObject TestObject; +typedef struct _TestObjectClass TestObjectClass; + +struct _TestObject +{ + GObject parent_instance; +}; +struct _TestObjectClass +{ + GObjectClass parent_class; +}; + +G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT); + +static void +test_object_finalize (GObject *object) +{ + object_destroyed = TRUE; + + G_OBJECT_CLASS (test_object_parent_class)->finalize (object); +} + +static void +test_object_class_init (TestObjectClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = test_object_finalize; +} + +static void +test_object_init (TestObject *test_object) +{ +} + +static void +clear_flags (void) +{ + object_destroyed = FALSE; + weak_ref1_notified = FALSE; + weak_ref2_notified = FALSE; + toggle_ref1_weakened = FALSE; + toggle_ref1_strengthened = FALSE; + toggle_ref2_weakened = FALSE; + toggle_ref2_strengthened = FALSE; + toggle_ref3_weakened = FALSE; + toggle_ref3_strengthened = FALSE; +} + +static void +weak_ref1 (gpointer data, + GObject *object) +{ + g_assert (object == global_object); + g_assert (data == GUINT_TO_POINTER (42)); + + weak_ref1_notified = TRUE; +} + +static void +weak_ref2 (gpointer data, + GObject *object) +{ + g_assert (object == global_object); + g_assert (data == GUINT_TO_POINTER (24)); + + weak_ref2_notified = TRUE; +} + +static void +toggle_ref1 (gpointer data, + GObject *object, + gboolean is_last_ref) +{ + g_assert (object == global_object); + g_assert (data == GUINT_TO_POINTER (42)); + + if (is_last_ref) + toggle_ref1_weakened = TRUE; + else + toggle_ref1_strengthened = TRUE; +} + +static void +toggle_ref2 (gpointer data, + GObject *object, + gboolean is_last_ref) +{ + g_assert (object == global_object); + g_assert (data == GUINT_TO_POINTER (24)); + + if (is_last_ref) + toggle_ref2_weakened = TRUE; + else + toggle_ref2_strengthened = TRUE; +} + +static void +toggle_ref3 (gpointer data, + GObject *object, + gboolean is_last_ref) +{ + g_assert (object == global_object); + g_assert (data == GUINT_TO_POINTER (34)); + + if (is_last_ref) + { + toggle_ref3_weakened = TRUE; + g_object_remove_toggle_ref (object, toggle_ref3, GUINT_TO_POINTER (34)); + } + else + toggle_ref3_strengthened = TRUE; +} + +int +main (int argc, + char *argv[]) +{ + GObject *object; + + g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) | + G_LOG_LEVEL_WARNING | + G_LOG_LEVEL_CRITICAL); + g_type_init (); + + /* Test basic weak reference operation + */ + global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL); + + g_object_weak_ref (object, weak_ref1, GUINT_TO_POINTER (42)); + + clear_flags (); + g_object_unref (object); + g_assert (weak_ref1_notified == TRUE); + g_assert (object_destroyed == TRUE); + + /* Test two weak references at once + */ + global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL); + + g_object_weak_ref (object, weak_ref1, GUINT_TO_POINTER (42)); + g_object_weak_ref (object, weak_ref2, GUINT_TO_POINTER (24)); + + clear_flags (); + g_object_unref (object); + g_assert (weak_ref1_notified == TRUE); + g_assert (weak_ref2_notified == TRUE); + g_assert (object_destroyed == TRUE); + + /* Test remove weak references + */ + global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL); + + g_object_weak_ref (object, weak_ref1, GUINT_TO_POINTER (42)); + g_object_weak_ref (object, weak_ref2, GUINT_TO_POINTER (24)); + g_object_weak_unref (object, weak_ref1, GUINT_TO_POINTER (42)); + + clear_flags (); + g_object_unref (object); + g_assert (weak_ref1_notified == FALSE); + g_assert (weak_ref2_notified == TRUE); + g_assert (object_destroyed == TRUE); + + /* Test basic toggle reference operation + */ + global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL); + + g_object_add_toggle_ref (object, toggle_ref1, GUINT_TO_POINTER (42)); + + clear_flags (); + g_object_unref (object); + g_assert (toggle_ref1_weakened == TRUE); + g_assert (toggle_ref1_strengthened == FALSE); + g_assert (object_destroyed == FALSE); + + clear_flags (); + g_object_ref (object); + g_assert (toggle_ref1_weakened == FALSE); + g_assert (toggle_ref1_strengthened == TRUE); + g_assert (object_destroyed == FALSE); + + g_object_unref (object); + + clear_flags (); + g_object_remove_toggle_ref (object, toggle_ref1, GUINT_TO_POINTER (42)); + g_assert (toggle_ref1_weakened == FALSE); + g_assert (toggle_ref1_strengthened == FALSE); + g_assert (object_destroyed == TRUE); + + global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL); + + /* Test two toggle references at once + */ + g_object_add_toggle_ref (object, toggle_ref1, GUINT_TO_POINTER (42)); + g_object_add_toggle_ref (object, toggle_ref2, GUINT_TO_POINTER (24)); + + clear_flags (); + g_object_unref (object); + g_assert (toggle_ref1_weakened == FALSE); + g_assert (toggle_ref1_strengthened == FALSE); + g_assert (toggle_ref2_weakened == FALSE); + g_assert (toggle_ref2_strengthened == FALSE); + g_assert (object_destroyed == FALSE); + + clear_flags (); + g_object_remove_toggle_ref (object, toggle_ref1, GUINT_TO_POINTER (42)); + g_assert (toggle_ref1_weakened == FALSE); + g_assert (toggle_ref1_strengthened == FALSE); + g_assert (toggle_ref2_weakened == TRUE); + g_assert (toggle_ref2_strengthened == FALSE); + g_assert (object_destroyed == FALSE); + + clear_flags (); + g_object_remove_toggle_ref (object, toggle_ref2, GUINT_TO_POINTER (24)); + g_assert (toggle_ref1_weakened == FALSE); + g_assert (toggle_ref1_strengthened == FALSE); + g_assert (toggle_ref2_weakened == FALSE); + g_assert (toggle_ref2_strengthened == FALSE); + g_assert (object_destroyed == TRUE); + + /* Test a toggle reference that removes itself + */ + global_object = object = g_object_new (TEST_TYPE_OBJECT, NULL); + + g_object_add_toggle_ref (object, toggle_ref3, GUINT_TO_POINTER (34)); + + clear_flags (); + g_object_unref (object); + g_assert (toggle_ref3_weakened == TRUE); + g_assert (toggle_ref3_strengthened == FALSE); + g_assert (object_destroyed == TRUE); + + return 0; +} |