unlock context when bailing out with a warning. (g_main_context_check):
authorTim Janik <timj@gtk.org>
Sun, 27 May 2001 18:28:58 +0000 (18:28 +0000)
committerTim Janik <timj@src.gnome.org>
Sun, 27 May 2001 18:28:58 +0000 (18:28 +0000)
Sun May 27 05:09:18 2001  Tim Janik  <timj@gtk.org>

        * gmain.c (g_main_context_prepare): unlock context when bailing
        out with a warning.
        (g_main_context_check): same here.

        * gmain.c (g_main_context_check): before returning due to
        changed pollfds, unlock context.

Sun May 27 04:52:28 2001  Tim Janik  <timj@gtk.org>

        * gsignal.[hc] (g_signal_stop_emission_by_name): added variant
        to stop signal emissions through a detailed_signal string.

        * gsignal.c (signal_emit_R) (g_signal_emit_valist): account for
        the fact that g_value_* functions may cause signal emissons by
        unlocking the global signal system lock around g_value_* functions.
        (signal_emit_unlocked_R): renamed this from signal_emit_R() to reflect
        that this functions acquires the lock on its own now.

15 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-12
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
glib/gmain.c
gmain.c
gmodule/ChangeLog
gmodule/gmodule.c
gobject/ChangeLog
gobject/gsignal.c
gobject/gsignal.h

index 9656ae2..5d299ed 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Sun May 27 05:09:18 2001  Tim Janik  <timj@gtk.org>
+
+       * gmain.c (g_main_context_prepare): unlock context when bailing
+       out with a warning.
+       (g_main_context_check): same here.
+
+       * gmain.c (g_main_context_check): before returning due to
+       changed pollfds, unlock context.
+       
 Thu May 24 21:24:16 CEST 2001 Paolo Molaro <lupus@ximian.com>
 
        * gmarkup.c: back out change by mitch@convergence.de and apply patch in
index 9656ae2..5d299ed 100644 (file)
@@ -1,3 +1,12 @@
+Sun May 27 05:09:18 2001  Tim Janik  <timj@gtk.org>
+
+       * gmain.c (g_main_context_prepare): unlock context when bailing
+       out with a warning.
+       (g_main_context_check): same here.
+
+       * gmain.c (g_main_context_check): before returning due to
+       changed pollfds, unlock context.
+       
 Thu May 24 21:24:16 CEST 2001 Paolo Molaro <lupus@ximian.com>
 
        * gmarkup.c: back out change by mitch@convergence.de and apply patch in
index 9656ae2..5d299ed 100644 (file)
@@ -1,3 +1,12 @@
+Sun May 27 05:09:18 2001  Tim Janik  <timj@gtk.org>
+
+       * gmain.c (g_main_context_prepare): unlock context when bailing
+       out with a warning.
+       (g_main_context_check): same here.
+
+       * gmain.c (g_main_context_check): before returning due to
+       changed pollfds, unlock context.
+       
 Thu May 24 21:24:16 CEST 2001 Paolo Molaro <lupus@ximian.com>
 
        * gmarkup.c: back out change by mitch@convergence.de and apply patch in
index 9656ae2..5d299ed 100644 (file)
@@ -1,3 +1,12 @@
+Sun May 27 05:09:18 2001  Tim Janik  <timj@gtk.org>
+
+       * gmain.c (g_main_context_prepare): unlock context when bailing
+       out with a warning.
+       (g_main_context_check): same here.
+
+       * gmain.c (g_main_context_check): before returning due to
+       changed pollfds, unlock context.
+       
 Thu May 24 21:24:16 CEST 2001 Paolo Molaro <lupus@ximian.com>
 
        * gmarkup.c: back out change by mitch@convergence.de and apply patch in
index 9656ae2..5d299ed 100644 (file)
@@ -1,3 +1,12 @@
+Sun May 27 05:09:18 2001  Tim Janik  <timj@gtk.org>
+
+       * gmain.c (g_main_context_prepare): unlock context when bailing
+       out with a warning.
+       (g_main_context_check): same here.
+
+       * gmain.c (g_main_context_check): before returning due to
+       changed pollfds, unlock context.
+       
 Thu May 24 21:24:16 CEST 2001 Paolo Molaro <lupus@ximian.com>
 
        * gmarkup.c: back out change by mitch@convergence.de and apply patch in
index 9656ae2..5d299ed 100644 (file)
@@ -1,3 +1,12 @@
+Sun May 27 05:09:18 2001  Tim Janik  <timj@gtk.org>
+
+       * gmain.c (g_main_context_prepare): unlock context when bailing
+       out with a warning.
+       (g_main_context_check): same here.
+
+       * gmain.c (g_main_context_check): before returning due to
+       changed pollfds, unlock context.
+       
 Thu May 24 21:24:16 CEST 2001 Paolo Molaro <lupus@ximian.com>
 
        * gmarkup.c: back out change by mitch@convergence.de and apply patch in
index 9656ae2..5d299ed 100644 (file)
@@ -1,3 +1,12 @@
+Sun May 27 05:09:18 2001  Tim Janik  <timj@gtk.org>
+
+       * gmain.c (g_main_context_prepare): unlock context when bailing
+       out with a warning.
+       (g_main_context_check): same here.
+
+       * gmain.c (g_main_context_check): before returning due to
+       changed pollfds, unlock context.
+       
 Thu May 24 21:24:16 CEST 2001 Paolo Molaro <lupus@ximian.com>
 
        * gmarkup.c: back out change by mitch@convergence.de and apply patch in
index 9656ae2..5d299ed 100644 (file)
@@ -1,3 +1,12 @@
+Sun May 27 05:09:18 2001  Tim Janik  <timj@gtk.org>
+
+       * gmain.c (g_main_context_prepare): unlock context when bailing
+       out with a warning.
+       (g_main_context_check): same here.
+
+       * gmain.c (g_main_context_check): before returning due to
+       changed pollfds, unlock context.
+       
 Thu May 24 21:24:16 CEST 2001 Paolo Molaro <lupus@ximian.com>
 
        * gmarkup.c: back out change by mitch@convergence.de and apply patch in
index 10905a2..6b1e69d 100644 (file)
@@ -1655,6 +1655,7 @@ g_main_context_prepare (GMainContext *context,
     {
       g_warning ("g_main_context_prepare() called recursively from within a source's check() or "
                 "prepare() member.");
+      UNLOCK_CONTEXT (context);
       return FALSE;
     }
 
@@ -1839,6 +1840,7 @@ g_main_context_check (GMainContext *context,
     {
       g_warning ("g_main_context_check() called recursively from within a source's check() or "
                 "prepare() member.");
+      UNLOCK_CONTEXT (context);
       return FALSE;
     }
   
@@ -1857,7 +1859,10 @@ g_main_context_check (GMainContext *context,
    * and let the main loop rerun
    */
   if (context->poll_changed)
-    return 0;
+    {
+      UNLOCK_CONTEXT (context);
+      return 0;
+    }
 #endif /* G_THREADS_ENABLED */
   
   pollrec = context->poll_records;
diff --git a/gmain.c b/gmain.c
index 10905a2..6b1e69d 100644 (file)
--- a/gmain.c
+++ b/gmain.c
@@ -1655,6 +1655,7 @@ g_main_context_prepare (GMainContext *context,
     {
       g_warning ("g_main_context_prepare() called recursively from within a source's check() or "
                 "prepare() member.");
+      UNLOCK_CONTEXT (context);
       return FALSE;
     }
 
@@ -1839,6 +1840,7 @@ g_main_context_check (GMainContext *context,
     {
       g_warning ("g_main_context_check() called recursively from within a source's check() or "
                 "prepare() member.");
+      UNLOCK_CONTEXT (context);
       return FALSE;
     }
   
@@ -1857,7 +1859,10 @@ g_main_context_check (GMainContext *context,
    * and let the main loop rerun
    */
   if (context->poll_changed)
-    return 0;
+    {
+      UNLOCK_CONTEXT (context);
+      return 0;
+    }
 #endif /* G_THREADS_ENABLED */
   
   pollrec = context->poll_records;
index 3a37a82..15e629e 100644 (file)
@@ -1,3 +1,10 @@
+Thu May 24 03:43:12 2001  Tim Janik  <timj@gtk.org>
+
+       * gmodule.c (g_module_open): reordered code so we have a single
+       module loading point (for reliable error messages). do access()
+       tests to figure plausible file names.
+       make error messages more verbose so users canfigure what's going on.
+
 2001-04-20  Dan Winship  <danw@ximian.com>
 
        * gmodule-dyld.c: gmodule implementation for Darwin/Mac OS X
index e006b8b..49cadf9 100644 (file)
@@ -124,12 +124,18 @@ g_module_find_by_name (const gchar *name)
 }
 
 static inline void
-g_module_set_error (const gchar *error)
+g_module_set_error_unduped (const gchar *error)
 {
   g_static_private_set (&module_error_private, g_strdup (error), g_free);
   errno = 0;
 }
 
+static inline void
+g_module_set_error (const gchar *error)
+{
+  g_module_set_error_unduped (g_strdup (error));
+}
+
 
 /* --- include platform specifc code --- */
 #define        SUPPORT_OR_RETURN(rv)   { g_module_set_error (NULL); }
@@ -200,7 +206,7 @@ parse_libtool_archive (const gchar* libtool_name)
   int fd = open (libtool_name, O_RDONLY, 0);
   if (fd < 0)
     {
-      g_module_set_error ("couldn't open libtool archive");   
+      g_module_set_error_unduped (g_strdup_printf ("failed to open libtool archive \"%s\"", libtool_name));   
       return NULL;
     }
   /* search libtool's dlname specification  */
@@ -224,7 +230,7 @@ parse_libtool_archive (const gchar* libtool_name)
              (token == TOKEN_INSTALLED ? 
               G_TOKEN_IDENTIFIER : G_TOKEN_STRING))
            {
-             g_module_set_error ("libtool archive has unknown format"); 
+             g_module_set_error_unduped (g_strdup_printf ("unable to parse libtool archive \"%s\"", libtool_name));
 
              g_free (lt_dlname);
              g_free (lt_libdir);
@@ -270,7 +276,8 @@ parse_libtool_archive (const gchar* libtool_name)
 }
 
 static inline gboolean
-g_str_check_suffix (const gchar* string, const gchar* suffix)
+str_check_suffix (const gchar* string,
+                 const gchar* suffix)
 {
   guint string_len = strlen (string);
   guint suffix_len = strlen (suffix);
@@ -286,7 +293,8 @@ g_module_open (const gchar    *file_name,
               GModuleFlags    flags)
 {
   GModule *module;
-  gpointer handle;
+  gpointer handle = NULL;
+  gchar *name = NULL;
   
   SUPPORT_OR_RETURN (NULL);
   
@@ -321,42 +329,49 @@ g_module_open (const gchar    *file_name,
       g_static_rec_mutex_unlock (&g_module_global_lock);
       return module;
     }
-  
-  /* First we try to open the module as provided */
-  handle = _g_module_open (file_name, (flags & G_MODULE_BIND_LAZY) != 0);
 
-  /* If not found, we check, if it is a libtool archive */
-  if (!handle && g_str_check_suffix (file_name, ".la"))
+  /* check whether we have a readable file right away */
+  if (g_file_test (file_name, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
+    name = g_strdup (file_name);
+  /* try completing file name with standard library suffix */
+  if (!name)
     {
-      gchar *name = parse_libtool_archive (file_name);
-      if (name)
+      name = g_strconcat (file_name, "." G_MODULE_SUFFIX, NULL);
+      if (!g_file_test (file_name, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
        {
-         handle = _g_module_open (name, (flags & G_MODULE_BIND_LAZY) != 0);
          g_free (name);
+         name = NULL;
        }
     }
-
-  /* If still not found, we check, if it is a library name without suffix */
-  if (!handle && !g_str_check_suffix (file_name, "." G_MODULE_SUFFIX))
+  /* last resort, try appending libtool suffix */
+  if (!name)
     {
-      gchar *name = g_strconcat (file_name, "." G_MODULE_SUFFIX, NULL);
-      handle = _g_module_open (name, (flags & G_MODULE_BIND_LAZY) != 0);
-      g_free (name);
+      name = g_strconcat (file_name, ".la");
+      if (!g_file_test (name, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
+       {
+         g_free (name);
+         name = NULL;
+       }
     }
 
-  /* If still not found, we check, if it is a libtool archive name
-   * without suffix */
-  if (!handle && !g_str_check_suffix (file_name, ".la"))
+  /* ok, try loading the module */
+  if (name)
     {
-      gchar *la_name = g_strconcat (file_name, ".la", NULL);
-      gchar *name = parse_libtool_archive (la_name);
-      if (name)
+      /* if it's a libtool archive, figure library file to load */
+      if (str_check_suffix (name, ".la")) /* libtool archive? */
        {
-         handle = _g_module_open (name, (flags & G_MODULE_BIND_LAZY) != 0);
+         gchar *real_name = parse_libtool_archive (name);
+
+         /* real_name might be NULL, but then module error is already set */
          g_free (name);
+         name = real_name;
        }
-      g_free (la_name);
+      if (name)
+       handle = _g_module_open (name, (flags & G_MODULE_BIND_LAZY) != 0);
     }
+  else
+    g_module_set_error_unduped (g_strdup_printf ("unable to access file \"%s\"", file_name));
+  g_free (name);
 
   if (handle)
     {
index 90889ec..f0595d4 100644 (file)
@@ -1,3 +1,14 @@
+Sun May 27 04:52:28 2001  Tim Janik  <timj@gtk.org>
+
+       * gsignal.[hc] (g_signal_stop_emission_by_name): added variant
+       to stop signal emissions through a detailed_signal string.
+
+       * gsignal.c (signal_emit_R) (g_signal_emit_valist): account for
+       the fact that g_value_* functions may cause signal emissons by
+       unlocking the global signal system lock around g_value_* functions.
+       (signal_emit_unlocked_R): renamed this from signal_emit_R() to reflect
+       that this functions acquires the lock on its own now.
+
 2001-05-24  Hans Breuer  <hans@breuer.org>
 
        * makefile.msc.in : changed depndencies to build glib-genmarshal
index a8920d8..f18a7c6 100644 (file)
@@ -142,7 +142,7 @@ static inline Emission*             emission_find           (Emission        *emission_list,
                                                         gpointer         instance);
 static gint                    signal_key_cmp          (gconstpointer    node1,
                                                         gconstpointer    node2);
-static       gboolean          signal_emit_R           (SignalNode      *node,
+static       gboolean          signal_emit_unlocked_R  (SignalNode      *node,
                                                         GQuark           detail,
                                                         gpointer         instance,
                                                         GValue          *return_value,
@@ -884,6 +884,51 @@ g_signal_parse_name (const gchar *detailed_signal,
   return TRUE;
 }
 
+void
+g_signal_stop_emission_by_name (gpointer     instance,
+                               const gchar *detailed_signal)
+{
+  guint signal_id;
+  GQuark detail = 0;
+  GType itype;
+  
+  g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
+  g_return_if_fail (detailed_signal != NULL);
+  
+  G_LOCK (g_signal_mutex);
+  itype = G_TYPE_FROM_INSTANCE (instance);
+  signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE);
+  if (signal_id)
+    {
+      SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id);
+      
+      if (detail && !(node->flags & G_SIGNAL_DETAILED))
+       g_warning ("%s: signal `%s' does not support details", G_STRLOC, detailed_signal);
+      else if (!g_type_is_a (itype, node->itype))
+       g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
+      else
+       {
+         Emission *emission_list = node->flags & G_SIGNAL_NO_RECURSE ? g_restart_emissions : g_recursive_emissions;
+         Emission *emission = emission_find (emission_list, signal_id, detail, instance);
+         
+         if (emission)
+           {
+             if (*emission->state_p == EMISSION_HOOK)
+               g_warning (G_STRLOC ": emission of signal \"%s\" for instance `%p' cannot be stopped from emission hook",
+                          node->name, instance);
+             else if (*emission->state_p == EMISSION_RUN)
+               *emission->state_p = EMISSION_STOP;
+           }
+         else
+           g_warning (G_STRLOC ": no emission of signal \"%s\" to stop for instance `%p'",
+                      node->name, instance);
+       }
+    }
+  else
+    g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
+  G_UNLOCK (g_signal_mutex);
+}
+
 guint
 g_signal_lookup (const gchar *name,
                  GType        itype)
@@ -1725,8 +1770,8 @@ g_signal_emitv (const GValue *instance_and_params,
     return_value = NULL;
 #endif /* G_ENABLE_DEBUG */
 
-  signal_emit_R (node, detail, instance, return_value, instance_and_params);
   G_UNLOCK (g_signal_mutex);
+  signal_emit_unlocked_R (node, detail, instance, return_value, instance_and_params);
 }
 
 void
@@ -1736,10 +1781,11 @@ g_signal_emit_valist (gpointer instance,
                      va_list  var_args)
 {
   GValue *instance_and_params, stack_values[MAX_STACK_VALUES], *free_me = NULL;
+  GType signal_return_type;
   GValue *param_values;
   SignalNode *node;
-  guint i;
-
+  guint i, n_params;
+  
   g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
   g_return_if_fail (signal_id > 0);
 
@@ -1760,6 +1806,8 @@ g_signal_emit_valist (gpointer instance,
     }
 #endif  /* !G_DISABLE_CHECKS */
 
+  n_params = node->n_params;
+  signal_return_type = node->return_type;
   if (node->n_params < MAX_STACK_VALUES)
     instance_and_params = stack_values;
   else
@@ -1771,12 +1819,15 @@ g_signal_emit_valist (gpointer instance,
   for (i = 0; i < node->n_params; i++)
     {
       gchar *error;
-
+      GType ptype = node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE;
+      gboolean static_scope = node->param_types[i] & G_SIGNAL_TYPE_STATIC_SCOPE;
+      
       param_values[i].g_type = 0;
-      g_value_init (param_values + i, node->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
+      G_UNLOCK (g_signal_mutex);
+      g_value_init (param_values + i, ptype);
       G_VALUE_COLLECT (param_values + i,
                       var_args,
-                      node->param_types[i] & G_SIGNAL_TYPE_STATIC_SCOPE ? G_VALUE_NOCOPY_CONTENTS : 0,
+                      static_scope ? G_VALUE_NOCOPY_CONTENTS : 0,
                       &error);
       if (error)
        {
@@ -1789,26 +1840,31 @@ g_signal_emit_valist (gpointer instance,
          while (i--)
            g_value_unset (param_values + i);
 
-         G_UNLOCK (g_signal_mutex);
          g_free (free_me);
          return;
        }
+      G_LOCK (g_signal_mutex);
     }
+  G_UNLOCK (g_signal_mutex);
   instance_and_params->g_type = 0;
   g_value_init (instance_and_params, G_TYPE_FROM_INSTANCE (instance));
   g_value_set_instance (instance_and_params, instance);
-  if (node->return_type == G_TYPE_NONE)
-    signal_emit_R (node, detail, instance, NULL, instance_and_params);
+  if (signal_return_type == G_TYPE_NONE)
+    signal_emit_unlocked_R (node, detail, instance, NULL, instance_and_params);
   else
     {
       GValue return_value = { 0, };
       gchar *error = NULL;
+      GType rtype = signal_return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE;
+      gboolean static_scope = signal_return_type & G_SIGNAL_TYPE_STATIC_SCOPE;
+      
+      g_value_init (&return_value, rtype);
+
+      signal_emit_unlocked_R (node, detail, instance, &return_value, instance_and_params);
 
-      g_value_init (&return_value, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
-      signal_emit_R (node, detail, instance, &return_value, instance_and_params);
       G_VALUE_LCOPY (&return_value,
                     var_args,
-                    node->return_type & G_SIGNAL_TYPE_STATIC_SCOPE ? G_VALUE_NOCOPY_CONTENTS : 0,
+                    static_scope ? G_VALUE_NOCOPY_CONTENTS : 0,
                     &error);
       if (!error)
        g_value_unset (&return_value);
@@ -1816,18 +1872,17 @@ g_signal_emit_valist (gpointer instance,
        {
          g_warning ("%s: %s", G_STRLOC, error);
          g_free (error);
-
+         
          /* we purposely leak the value here, it might not be
           * in a sane state if an error condition occoured
           */
        }
     }
-  for (i = 0; i < node->n_params; i++)
+  for (i = 0; i < n_params; i++)
     g_value_unset (param_values + i);
   g_value_unset (instance_and_params);
   if (free_me)
     g_free (free_me);
-  G_UNLOCK (g_signal_mutex);
 }
 
 void
@@ -1888,11 +1943,11 @@ accumulate (GSignalInvocationHint *ihint,
 }
 
 static gboolean
-signal_emit_R (SignalNode   *node,
-              GQuark        detail,
-              gpointer      instance,
-              GValue       *emission_return,
-              const GValue *instance_and_params)
+signal_emit_unlocked_R (SignalNode   *node,
+                       GQuark        detail,
+                       gpointer      instance,
+                       GValue       *emission_return,
+                       const GValue *instance_and_params)
 {
   EmissionState emission_state = 0;
   SignalAccumulator *accumulator;
@@ -1901,7 +1956,7 @@ signal_emit_R (SignalNode   *node,
   HandlerList *hlist;
   Handler *handler_list = NULL;
   GValue *return_accu, accu = { 0, };
-  guint signal_id = node->signal_id;
+  guint signal_id;
   gulong max_sequential_handler_number;
   gboolean return_value_altered = FALSE;
   
@@ -1917,6 +1972,8 @@ signal_emit_R (SignalNode   *node,
     }
 #endif /* G_ENABLE_DEBUG */
   
+  G_LOCK (g_signal_mutex);
+  signal_id = node->signal_id;
   if (node->flags & G_SIGNAL_NO_RECURSE)
     {
       Emission *emission = emission_find (g_restart_emissions, signal_id, detail, instance);
@@ -1932,8 +1989,10 @@ signal_emit_R (SignalNode   *node,
   accumulator = node->accumulator;
   if (accumulator)
     {
+      G_UNLOCK (g_signal_mutex);
       g_value_init (&accu, node->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
       return_accu = &accu;
+      G_LOCK (g_signal_mutex);
     }
   else
     return_accu = emission_return;
@@ -2157,6 +2216,7 @@ signal_emit_R (SignalNode   *node,
     handler_unref_R (signal_id, instance, handler_list);
   
   emission_pop ((node->flags & G_SIGNAL_NO_RECURSE) ? &g_restart_emissions : &g_recursive_emissions, &emission_state);
+  G_UNLOCK (g_signal_mutex);
   if (accumulator)
     g_value_unset (&accu);
   
index 696038d..ddcae80 100644 (file)
@@ -149,6 +149,8 @@ gboolean          g_signal_parse_name   (const gchar        *detailed_signal,
 void   g_signal_stop_emission              (gpointer             instance,
                                             guint                signal_id,
                                             GQuark               detail);
+void   g_signal_stop_emission_by_name      (gpointer             instance,
+                                            const gchar         *detailed_signal);
 gulong g_signal_add_emission_hook          (guint                signal_id,
                                             GQuark               quark,
                                             GSignalEmissionHook  hook_func,