[gupnp] Fix signals_autoconnect() call



commit 83013f6988c4ac3cba9c0aa0c40098524e5c238b
Author: Jens Georg <mail jensge org>
Date:   Sat Jul 11 23:41:26 2015 +0200

    Fix signals_autoconnect() call
    
    Use the introspection we get from the constructor, queue the autoconnects
    until this is ready. Also mark _get_instrospection() as deprecated.
    
    Signed-off-by: Jens Georg <mail jensge org>
    
    https://bugzilla.gnome.org/show_bug.cgi?id=750936

 libgupnp/gupnp-service-info.c |    8 ++++-
 libgupnp/gupnp-service.c      |   60 +++++++++++++++++++++++++++++++---------
 2 files changed, 52 insertions(+), 16 deletions(-)
---
diff --git a/libgupnp/gupnp-service-info.c b/libgupnp/gupnp-service-info.c
index 7e84303..4d76553 100644
--- a/libgupnp/gupnp-service-info.c
+++ b/libgupnp/gupnp-service-info.c
@@ -551,12 +551,16 @@ gupnp_service_info_get_event_subscription_url (GUPnPServiceInfo *info)
  * if the service does not provide an SCPD.
  *
  * Warning: You  should use gupnp_service_info_get_introspection_async()
- * instead, this function re-enter the GMainloop before returning.
+ * instead, this function re-enter the GMainloop before returning or might
+ * even block.
  *
  * Return value: (transfer full):  A new #GUPnPServiceIntrospection for this
  * service or %NULL. Unref after use.
+ *
+ * Deprecated: 0.20.15. Use gupnp_service_info_get_introspection_async() or
+ * gupnp_service_info_get_introspection_async_full() instead.
  **/
-GUPnPServiceIntrospection *
+G_DEPRECATED GUPnPServiceIntrospection *
 gupnp_service_info_get_introspection (GUPnPServiceInfo *info,
                                       GError          **error)
 {
diff --git a/libgupnp/gupnp-service.c b/libgupnp/gupnp-service.c
index 0655b94..825a66b 100644
--- a/libgupnp/gupnp-service.c
+++ b/libgupnp/gupnp-service.c
@@ -53,19 +53,23 @@ G_DEFINE_TYPE (GUPnPService,
                GUPNP_TYPE_SERVICE_INFO);
 
 struct _GUPnPServicePrivate {
-        GUPnPRootDevice *root_device;
+        GUPnPRootDevice           *root_device;
 
-        SoupSession     *session;
+        SoupSession               *session;
 
-        guint            notify_available_id;
+        guint                      notify_available_id;
 
-        GHashTable      *subscriptions;
+        GHashTable                *subscriptions;
 
-        GList           *state_variables;
+        GList                     *state_variables;
 
-        GQueue          *notify_queue;
+        GQueue                    *notify_queue;
 
-        gboolean         notify_frozen;
+        gboolean                   notify_frozen;
+
+        GUPnPServiceIntrospection *introspection;
+
+        GList                     *pending_autoconnect;
 };
 
 enum {
@@ -1381,6 +1385,26 @@ got_introspection (GUPnPServiceInfo          *info,
         gpointer data;
 
         if (introspection) {
+                /* Handle pending auto-connects */
+                service->priv->introspection  = g_object_ref (introspection);
+
+                /* _autoconnect() just calls prepend() so we reverse the list
+                 * here.
+                 */
+                service->priv->pending_autoconnect =
+                            g_list_reverse (service->priv->pending_autoconnect);
+
+                /* Re-call _autoconnect(). This will not fill
+                 * pending_autoconnect because we set the introspection member
+                 * variable before */
+                for (l = service->priv->pending_autoconnect; l; l = l->next)
+                        gupnp_service_signals_autoconnect (service,
+                                                           l->data,
+                                                           NULL);
+
+                g_list_free (service->priv->pending_autoconnect);
+                service->priv->pending_autoconnect = NULL;
+
                 state_variables =
                         gupnp_service_introspection_list_state_variables
                                 (introspection);
@@ -1638,6 +1662,11 @@ gupnp_service_finalize (GObject *object)
                 service->priv->session = NULL;
         }
 
+        if (service->priv->introspection) {
+                g_object_unref (service->priv->introspection);
+                service->priv->introspection = NULL;
+        }
+
         /* Call super */
         object_class = G_OBJECT_CLASS (gupnp_service_parent_class);
         object_class->finalize (object);
@@ -2232,19 +2261,23 @@ gupnp_service_signals_autoconnect (GUPnPService *service,
 
         g_return_if_fail (GUPNP_IS_SERVICE (service));
 
-        introspection = gupnp_service_info_get_introspection
-                                (GUPNP_SERVICE_INFO (service),
-                                 error);
-        if (!introspection)
+        introspection = service->priv->introspection;
+
+        if (!introspection) {
+                /* Initial introspection is not done yet, delay until we
+                 * received that */
+                service->priv->pending_autoconnect =
+                    g_list_prepend (service->priv->pending_autoconnect,
+                                    user_data);
+
                 return;
+        }
 
         /* Get a handle on the main executable -- use this to find symbols */
         module = g_module_open (NULL, 0);
         if (module == NULL) {
                 g_error ("Failed to open module: %s", g_module_error ());
 
-                g_object_unref (introspection);
-
                 return;
         }
 
@@ -2266,5 +2299,4 @@ gupnp_service_signals_autoconnect (GUPnPService *service,
                                           user_data);
 
         g_module_close (module);
-        g_object_unref (introspection);
 }


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