[glib] gsource: clarify restrictions on non-existant IDs



commit 1cbdbef77209fe82239bd10f062425491cf256ae
Author: Ryan Lortie <desrt desrt ca>
Date:   Tue Sep 16 19:40:30 2014 -0400

    gsource: clarify restrictions on non-existant IDs
    
    Document that one must not use the "by id" source APIs with non-existent
    IDs.  The real justification behind this restriction is that the reuse
    of source ids makes it unsafe to call these functions unless you're
    absolutely sure that the source exists and it belongs to you.  If you
    call one of these functions on a source that may already have been
    removed then you run the risk of finding someone else's source (with
    your reused id).
    
    This also bails us out of a slightly tricky situation with respect to
    the threadsafety of g_main_context_find_source_by_id().  The fact that
    this function doesn't return a reference implies that its return value
    cannot be safely accessed unless we already know for sure that a
    reference is being held elsewhere (by example, by the main context
    itself if we know that the source has not been removed).  The function
    itself, however, performs an access to the value, which could result in
    a crash.
    
    If we mandate that it is only valid to call this function on
    known-to-exist source IDs then we dodge this problem.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=736683

 glib/gmain.c |   34 +++++++++++++++++++++++++++++++++-
 1 files changed, 33 insertions(+), 1 deletions(-)
---
diff --git a/glib/gmain.c b/glib/gmain.c
index b68b65c..a6c8aef 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -1903,6 +1903,18 @@ g_source_get_name (GSource *source)
  * This is a convenience utility to set source names from the return
  * value of g_idle_add(), g_timeout_add(), etc.
  *
+ * It is a programmer error to attempt to set the name of a non-existent
+ * source.
+ *
+ * More specifically: source IDs can be reissued after a source has been
+ * destroyed and therefore it is never valid to use this function with a
+ * source ID which may have already been removed.  An example is when
+ * scheduling an idle to run in another thread with g_idle_add(): the
+ * idle may already have run and been removed by the time this function
+ * is called on its (now invalid) source ID.  This source ID may have
+ * been reissued, leading to the operation being performed against the
+ * wrong source.
+ *
  * Since: 2.26
  **/
 void
@@ -2043,7 +2055,18 @@ g_source_unref (GSource *source)
  *
  * Finds a #GSource given a pair of context and ID.
  *
- * Returns: (transfer none): the #GSource if found, otherwise, %NULL
+ * It is a programmer error to attempt to lookup a non-existent source.
+ *
+ * More specifically: source IDs can be reissued after a source has been
+ * destroyed and therefore it is never valid to use this function with a
+ * source ID which may have already been removed.  An example is when
+ * scheduling an idle to run in another thread with g_idle_add(): the
+ * idle may already have run and been removed by the time this function
+ * is called on its (now invalid) source ID.  This source ID may have
+ * been reissued, leading to the operation being performed against the
+ * wrong source.
+ *
+ * Returns: (transfer none): the #GSource
  **/
 GSource *
 g_main_context_find_source_by_id (GMainContext *context,
@@ -2178,6 +2201,15 @@ g_main_context_find_source_by_user_data (GMainContext *context,
  *
  * It is a programmer error to attempt to remove a non-existent source.
  *
+ * More specifically: source IDs can be reissued after a source has been
+ * destroyed and therefore it is never valid to use this function with a
+ * source ID which may have already been removed.  An example is when
+ * scheduling an idle to run in another thread with g_idle_add(): the
+ * idle may already have run and been removed by the time this function
+ * is called on its (now invalid) source ID.  This source ID may have
+ * been reissued, leading to the operation being performed against the
+ * wrong source.
+ *
  * Returns: For historical reasons, this function always returns %TRUE
  **/
 gboolean


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]