Add g_object_add/remove_toggle_ref() functions to get notification when a
authorOwen Taylor <otaylor@redhat.com>
Thu, 5 May 2005 14:57:29 +0000 (14:57 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Thu, 5 May 2005 14:57:29 +0000 (14:57 +0000)
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-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-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.

83 files changed:
ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-12
ChangeLog.pre-2-8
docs/reference/ChangeLog
docs/reference/glib/Makefile.am
docs/reference/glib/glib-sections.txt
docs/reference/glib/tmpl/allocators.sgml
docs/reference/glib/tmpl/arrays.sgml
docs/reference/glib/tmpl/arrays_pointer.sgml
docs/reference/glib/tmpl/async_queues.sgml
docs/reference/glib/tmpl/atomic_operations.sgml
docs/reference/glib/tmpl/byte_order.sgml
docs/reference/glib/tmpl/caches.sgml
docs/reference/glib/tmpl/conversions.sgml
docs/reference/glib/tmpl/datalist.sgml
docs/reference/glib/tmpl/datasets.sgml
docs/reference/glib/tmpl/date.sgml
docs/reference/glib/tmpl/error_reporting.sgml
docs/reference/glib/tmpl/fileutils.sgml
docs/reference/glib/tmpl/glib-unused.sgml
docs/reference/glib/tmpl/hash_tables.sgml
docs/reference/glib/tmpl/hooks.sgml
docs/reference/glib/tmpl/i18n.sgml
docs/reference/glib/tmpl/iochannels.sgml
docs/reference/glib/tmpl/keyfile.sgml
docs/reference/glib/tmpl/limits.sgml
docs/reference/glib/tmpl/linked_lists_double.sgml
docs/reference/glib/tmpl/linked_lists_single.sgml
docs/reference/glib/tmpl/macros.sgml
docs/reference/glib/tmpl/macros_misc.sgml
docs/reference/glib/tmpl/main.sgml
docs/reference/glib/tmpl/markup.sgml
docs/reference/glib/tmpl/memory.sgml
docs/reference/glib/tmpl/memory_chunks.sgml
docs/reference/glib/tmpl/messages.sgml
docs/reference/glib/tmpl/misc_utils.sgml
docs/reference/glib/tmpl/modules.sgml
docs/reference/glib/tmpl/numerical.sgml
docs/reference/glib/tmpl/option.sgml
docs/reference/glib/tmpl/patterns.sgml
docs/reference/glib/tmpl/quarks.sgml
docs/reference/glib/tmpl/queue.sgml
docs/reference/glib/tmpl/random_numbers.sgml
docs/reference/glib/tmpl/relations.sgml
docs/reference/glib/tmpl/scanner.sgml
docs/reference/glib/tmpl/shell.sgml
docs/reference/glib/tmpl/spawn.sgml
docs/reference/glib/tmpl/string_chunks.sgml
docs/reference/glib/tmpl/string_utils.sgml
docs/reference/glib/tmpl/strings.sgml
docs/reference/glib/tmpl/thread_pools.sgml
docs/reference/glib/tmpl/threads.sgml
docs/reference/glib/tmpl/timers.sgml
docs/reference/glib/tmpl/trash_stack.sgml
docs/reference/glib/tmpl/trees-binary.sgml
docs/reference/glib/tmpl/trees-nary.sgml
docs/reference/glib/tmpl/type_conversion.sgml
docs/reference/glib/tmpl/types.sgml
docs/reference/glib/tmpl/unicode.sgml
docs/reference/glib/tmpl/version.sgml
docs/reference/glib/tmpl/warnings.sgml
docs/reference/gobject/gobject-sections.txt
docs/reference/gobject/tmpl/gboxed.sgml
docs/reference/gobject/tmpl/gclosure.sgml
docs/reference/gobject/tmpl/gparamspec.sgml
docs/reference/gobject/tmpl/gtypeplugin.sgml
docs/reference/gobject/tmpl/objects.sgml
docs/reference/gobject/tmpl/param_value_types.sgml
docs/reference/gobject/tmpl/value_collection.sgml
glib/Makefile.am
glib/gdataset.c
glib/gdataset.h
glib/gdatasetprivate.h [new file with mode: 0644]
glib/gfileutils.c
glib/gfileutils.h
glib/glib.symbols
gobject/ChangeLog
gobject/gobject.c
gobject/gobject.h
gobject/gobject.symbols
tests/gobject/Makefile.am
tests/gobject/references.c [new file with mode: 0644]

index 19a94687bcf40b73d61b4bfc95937184f1187958..fbc9501d71c3d44f9994894103acdec5d97fd44f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
index 19a94687bcf40b73d61b4bfc95937184f1187958..fbc9501d71c3d44f9994894103acdec5d97fd44f 100644 (file)
@@ -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
index 19a94687bcf40b73d61b4bfc95937184f1187958..fbc9501d71c3d44f9994894103acdec5d97fd44f 100644 (file)
@@ -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
index 19a94687bcf40b73d61b4bfc95937184f1187958..fbc9501d71c3d44f9994894103acdec5d97fd44f 100644 (file)
@@ -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
index bda5fd3d1e40b3eb2e4bb716616919ed2cd10879..6511da76ae5aaff87a73f78a09a788e40bdf260b 100644 (file)
@@ -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.
index aac0f9ee34b88e5beede369b5a718c9444865d15..45fa09928787d1070f4ee4cabd722810dc5eec0f 100644 (file)
@@ -22,6 +22,7 @@ IGNORE_HFILES=                        \
        build                   \
        gobject                 \
        config.h                \
+       gdatasetprivate.h       \
        glibintl.h              \
        gbsearcharray.h         \
        gmoduleconf.h           \
index e1f0d09f545683726c3788920287fa287a45b5ba..9a5f8bb41619f829729e509abcd9ec0664d8c5c9 100644 (file)
@@ -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>
 
 
index a98496c81db40d40d849a0b9594cda0ec2e9653c..54eb60bbbfde432e1e591aecaca5464be28df75b 100644 (file)
@@ -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
index 86dd0f269ccfc4f57d20d8609610eeed5bacefbe..47092c19dfa78a9b9f4199f755b8e7c51650ea7a 100644 (file)
@@ -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>.
index a1b23a524a005b8ced10f1f940ee2a00f980c083..0c912d9fbdce63d1ab13143437fc890a30771bc4 100644 (file)
@@ -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.
index b9ffef3132c3b556e0831672c1ebbc78f989408f..d256421992617bf61d5c0f4e7c2595e5b77eccdf 100644 (file)
@@ -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
index bccb0fe3653acd9ec65342026c3119d05cdedbbf..7025080efc0c36e66f2d68734de00f44d0b132c2 100644 (file)
@@ -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
index 01e931c9a6fcdc8aca9ee11956db77c1179854c6..3006a48e241fb044257100a62f5ae2fa145a022e 100644 (file)
@@ -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.
index 71b8b6fc9a9ae7eadc94ed2cae3e4ad1f56332bd..bdda2116d5490c38b952d33d4edd3b66b5225238 100644 (file)
@@ -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
index 9f9238788351b79944ed6986381c4f410f284af5..41a633216e5b873c4a6765d7444220b20f51a7a7 100644 (file)
@@ -161,6 +161,9 @@ export G_FILENAME_ENCODING=ISO-8859-1
 
 </para>
 
+<!-- ##### SECTION Stability_Level ##### -->
+
+
 <!-- ##### FUNCTION g_convert ##### -->
 <para>
 
index fea61b65e83ecbfc40a0d85bf3d3b9558e636137..c2690ea4acd6efab06674219e831000849426ab2 100644 (file)
@@ -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>
+
+
+
index 1afdf6cf35824153a149825e14bcb88e45af491c..815294c501437e775cf51e02f7dbaefae71eae31 100644 (file)
@@ -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.
index 046265b82406b9ea20ed3afe5652a16c0dfcf47e..57d9cc87cf99ee18d57b3fb2acb94ffe4fdb163c 100644 (file)
@@ -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
index 6b555a1a77d358ec6755c093cb2f9aa77b877e84..fa1604e9c4e70aac5a09a4bcd88f9bc89b83b5a6 100644 (file)
@@ -370,6 +370,9 @@ Summary of rules for use of #GError:
 
 </para>
 
+<!-- ##### SECTION Stability_Level ##### -->
+
+
 <!-- ##### STRUCT GError ##### -->
 <para>
 The <structname>GError</structname> structure contains 
index e7deae8840012fddd564b032b26604db34b98cb8..63549f2ad134c40ebfdc8edef88a36d372962ed5 100644 (file)
@@ -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: 
+
+
index 6cd8c10d083e9833ce74bb5d9dd7006441236ec3..b089e668638f564fd2cbb3d7b9f56b7dd2c86cb3 100644 (file)
@@ -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>
 
index 339e80770c64acd5f164e8d7b72c04de2d48e7e4..f1798f93af101123a19734d90579ab8dad38164a 100644 (file)
@@ -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: 
 
 
index 14ea223f1ceb2f4c8c5b4b36c70d2770b8f1b1e2..666e6d79bf5c3d66691a2f29712d8ae3bd69ae67 100644 (file)
@@ -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 
index fc34eb1337d9a51d641c08fe67ba666f335bca3e..391ea95abeb7f2fe5efabb5bfc0408e59e1d87aa 100644 (file)
@@ -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
index 7ae3245ee2758efe78608f68f7c61e7b3100db71..57219fcacaf0a6e4f2eb9553d5dfddb6bb19cc5a 100644 (file)
@@ -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
index bd5a3c84e445ab9b6cfab6d0779f8999e1c5cc5c..18f3969165a37f7ead74079c12bc1e6f2857f6e9 100644 (file)
@@ -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
index 44d28a6bc91a760009d44c089991ba1491cd2cf9..038b5b4046d42d1e0f6296772bb1a6c5a5571f7a 100644 (file)
@@ -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.
index 28902757a14fad801d9a84f41a0a1ada09c1214f..f0398bb1c01a93b43b9b29c2675bbbf9c08acf77 100644 (file)
@@ -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.
index 17a004cbf2e0f3007ce6ff7b996a73e5f1563fdf..64b7cf705f188d12240019398f2e9278a31dcb81 100644 (file)
@@ -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.
index 131bc02fae070a0de3342cb5a20a6c423a1a061f..e453ed2f5825bc724ac7e7b460315db0acfa9ffc 100644 (file)
@@ -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
index eacb95dba6265955794c7a4f2af8846e1e7ab484..0d070d775b8df028b87d335ec6aea58b932ae53c 100644 (file)
@@ -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 
index d9a8e3454c3e505c842f16ef4c06109d597c5a53..38b35221609df4f738f1306b97674a17d6f14bf7 100644 (file)
@@ -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 
index c795ee513566eb33c398e027febcaa2edc54cb1b..76abdda5dbed829709db29b3e8f6a2adf4f8822b 100644 (file)
@@ -85,6 +85,9 @@ Sections marked as CDATA
 
 </para>
 
+<!-- ##### SECTION Stability_Level ##### -->
+
+
 <!-- ##### ENUM GMarkupError ##### -->
 <para>
 Error codes returned by markup parsing.
index 7c5f8f4e1ed1efd6b5f62537dda704483ad04614..063b7a94957ed982bd78d723e2ae53f161fb5a9a 100644 (file)
@@ -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 ##### -->
index 2fbe0c0ac090bec9fd0628fa125379ace5204294..519904d61c7adf00682f2b6a930eaf3536b7c2f6 100644 (file)
@@ -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
index 4e04bfc1b03bd5bcd3a1870bc2064d742966ccdd..3854f300274bd5679b207e80cb9e500645b8efc0 100644 (file)
@@ -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.
index bea827583305b352b6c6ffc921eafe7794896cb2..eb32d3bce0c175e2eabe81670e8524f9c3abd61f 100644 (file)
@@ -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 ##### -->
index db2e00070264314a5ca94c92aac35d6a68273ac7..0364423b5dd1bd904c74ad211ef5441da8cb6a0f 100644 (file)
@@ -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
index 1466dd385df92ef5ca879081bddd6755cce21b23..d9c5ac24c30bd1bdf651af13f34cb968bf7cc219 100644 (file)
@@ -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>
index 7363cb00b230cc4d5d9aeb6090d2a146f035ed79..3aa2c1b46be3254893b8f85d7d06a68ee5d27845 100644 (file)
@@ -124,6 +124,9 @@ main (int argc, char *argv[])
 
 </para>
 
+<!-- ##### SECTION Stability_Level ##### -->
+
+
 <!-- ##### ENUM GOptionError ##### -->
 <para>
 Error codes returned by option parsing.
index bcaf12d13f330cea443fdbace1dd8034d1a2345c..48d6661fdc8376c07bcf91c99c056759f4f894fc 100644 (file)
@@ -30,6 +30,9 @@ pattern compilation.
 
 </para>
 
+<!-- ##### SECTION Stability_Level ##### -->
+
+
 <!-- ##### STRUCT GPatternSpec ##### -->
 <para>
 A <structname>GPatternSpec</structname> is the 'compiled' form of a pattern.
index 9a531f3d83183baee988bac481207ee9a74800f7..7a8159edfdb0b251288bd10b4f37fbc65a893c22 100644 (file)
@@ -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.
index 6b5e8689dd508336d9cf0cb51513c5f7b864a678..44e262091bace051dbe69561a3c5b448a29d5541 100644 (file)
@@ -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>.
index 1dbdc61c9badb64cc036a7be836456fab00a9079..947897ef010be8921e1f775c670f2e8f031c789e 100644 (file)
@@ -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
index 102f0fb417eb4bb0d0792505fa0b4bdae614d887..3b34fc18821c55043fd73ae317aed5e770e63f19 100644 (file)
@@ -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
index bac9d601affe1c8ba56e0e8bcc8821751d714f5e..494b1d278c80e755063af4f96f44bfd264996b0f 100644 (file)
@@ -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.
index 399aa4f57c332858aa7a8e6fd9e550189b6b20fd..b2304e639aa1df1fcf45a64c9d97ec0d3366efea 100644 (file)
@@ -14,6 +14,9 @@ shell-like commandline handling.
 
 </para>
 
+<!-- ##### SECTION Stability_Level ##### -->
+
+
 <!-- ##### ENUM GShellError ##### -->
 <para>
 Error codes returned by shell functions.
index 36615b444c77ed6cf404055562f4b78af5cbf8a0..871433696c4b79a88ae22e20d56e73ce53288fb5 100644 (file)
@@ -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.
index 4b5fcba0ccd8673ea8b741b8c808d5709772fb13..d6fa6a7809e8828c56bca6a719afcf14233de5d4 100644 (file)
@@ -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.
index a772d9584e31d2cc438f1290a8aaba161f5cb8eb..0fce6c4de8588417c8dc0f07f3316b170e36f41a 100644 (file)
@@ -37,6 +37,9 @@ wide characters (see g_unichar_iswide()) into account.
 
 </para>
 
+<!-- ##### SECTION Stability_Level ##### -->
+
+
 <!-- ##### FUNCTION g_strdup ##### -->
 <para>
 Duplicates a string.
index 24fa7edb475a96430f13ce00c2090a87c7aa9707..fb68ae17fe1b219b0c1cc9e99155b53cf7f14e9f 100644 (file)
@@ -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.
index a13629a3edc9f31be769607a99fe73b48e056bfd..1ce7446a7ba9d7b6615bc020ff96caab571e27d6 100644 (file)
@@ -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
index 72104c40f397131fb48454c54c5907871803eeb0..e84bb98c55f852860b56f0a5d5c15a2279a410e3 100644 (file)
@@ -49,6 +49,9 @@ primitives to portably create and manage threads (#GThread).
 </variablelist>
 </para>
 
+<!-- ##### SECTION Stability_Level ##### -->
+
+
 <!-- ##### MACRO G_THREADS_ENABLED ##### -->
 
 <para>
index 59dacc5ccfd8a4c9f18783fc8922e445df17134a..d361c9fed1bf59bc5208a635dce706d7cf68fd38 100644 (file)
@@ -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. 
index d91bf4ceb4cce20bce987aac31ad8a7930c65ed6..ac1fa3844d879d7f52ad4bbced992ff6df8de60e 100644 (file)
@@ -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
index d3838a86f592ef8b019294cc8a9f651a53fe540c..36db07216634fcb0d72fc0f2ad53a74413bcd62f 100644 (file)
@@ -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
index 6259925af03743ddbd716200b1b3f37154cb644e..3cdbc436f8b770f4964e67833ac1efa631f7ffe4 100644 (file)
@@ -49,6 +49,9 @@ g_node_destroy().
 
 </para>
 
+<!-- ##### SECTION Stability_Level ##### -->
+
+
 <!-- ##### STRUCT GNode ##### -->
 <para>
 The <structname>GNode</structname> struct represents one node in a
index 41527e5cbc929821db2549b51916e263c5d588d0..6d204e5be2506abc884a6d9cf489143d8fab4d97 100644 (file)
@@ -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.
index d9eec444577f5cb0eb57c8850ce427e16ff436df..f618a34d1a786dbd6b7c26f3f45900b02c136291 100644 (file)
@@ -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.
index 1f197ddb2bf2bca1cda2f9f1c2a50eccb7ee7a46..994297f2b514da429cffbbde21fb5bc48e697d74 100644 (file)
@@ -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. 
index 0a2feda132dea1fa84a09cfec2e1962dac20fd86..f46c1e1a59fc471cc4c90f7583b4dd9476491119 100644 (file)
@@ -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. 
index 2bc97171f16889f4afba7aa07a6d5d44a55891a8..9db10dacffaba7a3cae50c790f09f44698974834 100644 (file)
@@ -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.
index f42e01c2b464d20f78a238df8aea49f50ef16e43..dc4917c4d5b0465afbc05eb71675c9a35aa788e3 100644 (file)
@@ -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
index 84aeb7f58303fdedce61cf4cad1663f72224e1a8..fd178e2538eaf9c60bc0a09babf6619cb19cde7e 100644 (file)
@@ -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
index d4e2e413e494ae4da9fcfd2013be173552f8b853..3c9d80ada5b27d95ae82d6e43d2c07a27eb5bf45 100644 (file)
@@ -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 
index 167ebc1a89f015518ab9c619f9dbafa8d548fbc0..18f63bf0e79f1e58e2f1c9af90b688a26fb3f919 100644 (file)
@@ -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.
index d33914832f924b7bf1f0fc6820c858fa73982490..07b535f7e3d47525cc54423759e5c6abeabd3b7e 100644 (file)
@@ -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 
index 0f3f4cc324b3836ecbee26ae9f032e579a511340..3ac2f9dd2eeb13f2d583886a3c6a215ca574eaf4 100644 (file)
@@ -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.
index 1fb32ec6ab6c54079b358be2df4e4bb4610a17af..f5bd46c10e9920095347d5f8e53a77f11a15ec56 100644 (file)
@@ -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>
index e33b486274a88f2602e8dde1d727ef5b422bd5f4..2f7ec68f6ca2d8be9d303f6da498ea867823200f 100644 (file)
@@ -14,6 +14,9 @@ Converting varargs to generic values
 
 </para>
 
+<!-- ##### SECTION Stability_Level ##### -->
+
+
 <!-- ##### UNION GTypeCValue ##### -->
 <para>
 A union holding one collected value.
index de504e2780445160641cf2df271b2ae90bb6dba6..527cf3cf1c639c641740a14142c62e78c949dee2 100644 (file)
@@ -70,6 +70,7 @@ libglib_2_0_la_SOURCES =      \
        gcompletion.c           \
        gconvert.c              \
        gdataset.c              \
+       gdatasetprivate.h       \
        gdate.c                 \
        gdir.c                  \
        gerror.c                \
index fbd9c2da43ad9819cdd84ede02cd1986cabdfbff..43580e46a0a3447908e2fa6b23d34e3f4abc3beb 100644 (file)
@@ -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)
index e04a706c102764c58e0fe3f9afaa87215b7702b5..0376cac979d5965f3d2d80a18b54188c78c8dd02 100644 (file)
@@ -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 (file)
index 0000000..1a2e319
--- /dev/null
@@ -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__ */
index cf21c061bf70df9f66025ef3433a985c15c42876..d0dd3ce53d2cc51d24b5ee233b3b5883745bb3d1 100644 (file)
@@ -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;
index 2e82d3f39cb8072f2db16496a521c24a0eed4294..7c23cadd3d68e9620bba833566420ca8350df102 100644 (file)
@@ -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);
index f08e034552db1fa93e73136fe8beed0ce0bbe132..00831ec46d2b847a1b65bc3cd6a5337640b48895 100644 (file)
@@ -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
index fde059539277b586526b156dbb2fe5b9fb2d6b67..90c45e0d528c599a773eac5efb18067fd3d03add 100644 (file)
@@ -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: 
index 723b65f9030e1efcc764fd54a141196a1ef0b93f..aaf4d54a7e3d27f6478b309bc6b7fe9dde0ac00c 100644 (file)
@@ -18,6 +18,7 @@
  */
 #include       "gobject.h"
 #include       "gobjectalias.h"
+#include        <glib/gdatasetprivate.h>
 
 /*
  * MT safe
 #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);
 }
index f3935ca9e3334d26225f1d7b4aa9bd13899282ca..e835e73487c61bc12c92a9b4dd284212d2569d71 100644 (file)
@@ -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,
index 7b32ea15ae3b49e575959d7a30958538d084c23f..9af8c9a963b3570d1c54c5c1810ad7bc10537602 100644 (file)
@@ -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
index b09d4de62f205d82f650069c7af5683b7411a033..778b535547c93a1d3e1744d6b04f3f25b5959e03 100644 (file)
@@ -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 (file)
index 0000000..86c700f
--- /dev/null
@@ -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;
+}