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 19a9468..fbc9501 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 19a9468..fbc9501 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 19a9468..fbc9501 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 19a9468..fbc9501 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 bda5fd3..6511da7 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 aac0f9e..45fa099 100644 (file)
@@ -22,6 +22,7 @@ IGNORE_HFILES=                        \
        build                   \
        gobject                 \
        config.h                \
+       gdatasetprivate.h       \
        glibintl.h              \
        gbsearcharray.h         \
        gmoduleconf.h           \
index e1f0d09..9a5f8bb 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 a98496c..54eb60b 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 86dd0f2..47092c1 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 a1b23a5..0c912d9 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 b9ffef3..d256421 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 bccb0fe..7025080 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 01e931c..3006a48 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 71b8b6f..bdda211 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 9f92387..41a6332 100644 (file)
@@ -161,6 +161,9 @@ export G_FILENAME_ENCODING=ISO-8859-1
 
 </para>
 
+<!-- ##### SECTION Stability_Level ##### -->
+
+
 <!-- ##### FUNCTION g_convert ##### -->
 <para>
 
index fea61b6..c2690ea 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 1afdf6c..815294c 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 046265b..57d9cc8 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 6b555a1..fa1604e 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 e7deae8..63549f2 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 6cd8c10..b089e66 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 339e807..f1798f9 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 14ea223..666e6d7 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 fc34eb1..391ea95 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 7ae3245..57219fc 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 bd5a3c8..18f3969 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 44d28a6..038b5b4 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 2890275..f0398bb 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 17a004c..64b7cf7 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 131bc02..e453ed2 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 eacb95d..0d070d7 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 d9a8e34..38b3522 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 c795ee5..76abdda 100644 (file)
@@ -85,6 +85,9 @@ Sections marked as CDATA
 
 </para>
 
+<!-- ##### SECTION Stability_Level ##### -->
+
+
 <!-- ##### ENUM GMarkupError ##### -->
 <para>
 Error codes returned by markup parsing.
index 7c5f8f4..063b7a9 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 2fbe0c0..519904d 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 4e04bfc..3854f30 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 bea8275..eb32d3b 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 db2e000..0364423 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 1466dd3..d9c5ac2 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 7363cb0..3aa2c1b 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 bcaf12d..48d6661 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 9a531f3..7a8159e 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 6b5e868..44e2620 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 1dbdc61..947897e 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 102f0fb..3b34fc1 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 bac9d60..494b1d2 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 399aa4f..b2304e6 100644 (file)
@@ -14,6 +14,9 @@ shell-like commandline handling.
 
 </para>
 
+<!-- ##### SECTION Stability_Level ##### -->
+
+
 <!-- ##### ENUM GShellError ##### -->
 <para>
 Error codes returned by shell functions.
index 36615b4..8714336 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 4b5fcba..d6fa6a7 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 a772d95..0fce6c4 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 24fa7ed..fb68ae1 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 a13629a..1ce7446 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 72104c4..e84bb98 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 59dacc5..d361c9f 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 d91bf4c..ac1fa38 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 d3838a8..36db072 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 6259925..3cdbc43 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 41527e5..6d204e5 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 d9eec44..f618a34 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 1f197dd..994297f 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 0a2feda..f46c1e1 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 2bc9717..9db10da 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 f42e01c..dc4917c 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 84aeb7f..fd178e2 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 d4e2e41..3c9d80a 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 167ebc1..18f63bf 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 d339148..07b535f 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 0f3f4cc..3ac2f9d 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 1fb32ec..f5bd46c 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 e33b486..2f7ec68 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 de504e2..527cf3c 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 fbd9c2d..43580e4 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 e04a706..0376cac 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 cf21c06..d0dd3ce 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 2e82d3f..7c23cad 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 f08e034..00831ec 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 fde0595..90c45e0 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 723b65f..aaf4d54 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 f3935ca..e835e73 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 7b32ea1..9af8c9a 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 b09d4de..778b535 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;
+}