[libgweather/gnome-3-10] GWeatherInfo: don't abort the entire SoupSession



commit d5695b1183ad4d895dae24a6048b8788f9e8d7d0
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Sat Mar 8 19:34:18 2014 +0100

    GWeatherInfo: don't abort the entire SoupSession
    
    The SoupSession is shared between all GWeatherInfos, so it's
    extremely bad to abort it, expecially because we do when infos
    are finalized. Instead, have each info keep a list of pending
    SoupMessages and cancel them.

 libgweather/weather-iwin.c  |   11 ++++++-----
 libgweather/weather-metar.c |   12 ++++++------
 libgweather/weather-owm.c   |   12 ++++++------
 libgweather/weather-priv.h  |    7 +++++--
 libgweather/weather-wx.c    |   13 +++++++------
 libgweather/weather-yahoo.c |   12 ++++++------
 libgweather/weather-yrno.c  |   24 ++++++++++++------------
 libgweather/weather.c       |   37 +++++++++++++++++++++++++++++++------
 8 files changed, 79 insertions(+), 49 deletions(-)
---
diff --git a/libgweather/weather-iwin.c b/libgweather/weather-iwin.c
index 5961878..1bc60f5 100644
--- a/libgweather/weather-iwin.c
+++ b/libgweather/weather-iwin.c
@@ -322,16 +322,17 @@ iwin_finish (SoupSession *session, SoupMessage *msg, gpointer data)
 
     if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
         /* forecast data is not really interesting anyway ;) */
-        g_warning ("Failed to get IWIN forecast data: %d %s\n",
-                   msg->status_code, msg->reason_phrase);
-        _gweather_info_request_done (info);
+       if (msg->status_code != SOUP_STATUS_CANCELLED)
+           g_warning ("Failed to get IWIN forecast data: %d %s\n",
+                      msg->status_code, msg->reason_phrase);
+        _gweather_info_request_done (info, msg);
         return;
     }
 
     priv = info->priv;
     priv->forecast_list = parseForecastXml (msg->response_body->data, info);
 
-    _gweather_info_request_done (info);
+    _gweather_info_request_done (info, msg);
 }
 
 /* Get forecast into newly alloc'ed string */
@@ -370,9 +371,9 @@ iwin_start_open (GWeatherInfo *info)
     url = g_strdup_printf 
("http://www.weather.gov/forecasts/xml/sample_products/browser_interface/ndfdBrowserClientByDay.php?&lat=%s&lon=%s&format=24+hourly&startDate=%04d-%02d-%02d&numDays=7";,
                           latstr, lonstr, 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday);
     msg = soup_message_new ("GET", url);
+    _gweather_info_begin_request (info, msg);
     soup_session_queue_message (priv->session, msg, iwin_finish, info);
 
-    priv->requests_pending++;
     g_free (url);
 
     return TRUE;
diff --git a/libgweather/weather-metar.c b/libgweather/weather-metar.c
index 94ff2cc..d808e43 100644
--- a/libgweather/weather-metar.c
+++ b/libgweather/weather-metar.c
@@ -570,11 +570,12 @@ metar_finish (SoupSession *session, SoupMessage *msg, gpointer data)
            priv->network_error = TRUE;
        else {
            /* Translators: %d is an error code, and %s the error string */
-           g_warning (_("Failed to get METAR data: %d %s.\n"),
-                      msg->status_code, msg->reason_phrase);
+           if (msg->status_code != SOUP_STATUS_CANCELLED)
+               g_warning (_("Failed to get METAR data: %d %s.\n"),
+                          msg->status_code, msg->reason_phrase);
        }
 
-       _gweather_info_request_done (info);
+       _gweather_info_request_done (info, msg);
        return;
     }
 
@@ -601,7 +602,7 @@ metar_finish (SoupSession *session, SoupMessage *msg, gpointer data)
     }
 
     priv->valid = success;
-    _gweather_info_request_done (info);
+    _gweather_info_request_done (info, msg);
 }
 
 /* Read current conditions and fill in info structure */
@@ -623,7 +624,6 @@ metar_start_open (GWeatherInfo *info)
        "GET", "http://weather.noaa.gov/cgi-bin/mgetmetar.pl";,
        "cccc", loc->code,
        NULL);
+    _gweather_info_begin_request (info, msg);
     soup_session_queue_message (priv->session, msg, metar_finish, info);
-
-    priv->requests_pending++;
 }
diff --git a/libgweather/weather-owm.c b/libgweather/weather-owm.c
index 40a8832..b23cd56 100644
--- a/libgweather/weather-owm.c
+++ b/libgweather/weather-owm.c
@@ -400,14 +400,15 @@ owm_finish (SoupSession *session,
 
     if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
        /* forecast data is not really interesting anyway ;) */
-       g_message ("Failed to get OpenWeatherMap forecast data: %d %s\n",
-                  msg->status_code, msg->reason_phrase);
-       _gweather_info_request_done (info);
+       if (msg->status_code != SOUP_STATUS_CANCELLED)
+           g_message ("Failed to get OpenWeatherMap forecast data: %d %s\n",
+                      msg->status_code, msg->reason_phrase);
+       _gweather_info_request_done (info, msg);
        return;
     }
 
     parse_forecast_xml (info, msg->response_body);
-    _gweather_info_request_done (info);
+    _gweather_info_request_done (info, msg);
 }
 
 gboolean
@@ -440,10 +441,9 @@ owm_start_open (GWeatherInfo *info)
     url = g_strdup_printf (template, latstr, lonstr);
 
     message = soup_message_new ("GET", url);
+    _gweather_info_begin_request (info, message);
     soup_session_queue_message (priv->session, message, owm_finish, info);
 
-    priv->requests_pending++;
-
     g_free (url);
 
     return TRUE;
diff --git a/libgweather/weather-priv.h b/libgweather/weather-priv.h
index c9e4b73..8bea95b 100644
--- a/libgweather/weather-priv.h
+++ b/libgweather/weather-priv.h
@@ -133,7 +133,7 @@ struct _GWeatherInfoPrivate {
     GdkPixbufLoader *radar_loader;
     GdkPixbufAnimation *radar;
     SoupSession *session;
-    gint requests_pending;
+    GSList *requests_pending;
 };
 
 /* Values common to the parsing source files */
@@ -190,7 +190,10 @@ gboolean        owm_start_open          (GWeatherInfo *info);
 gboolean       metar_parse             (gchar *metar,
                                         GWeatherInfo *info);
 
-void           _gweather_info_request_done (GWeatherInfo *info);
+void            _gweather_info_begin_request (GWeatherInfo *info,
+                                             SoupMessage  *message);
+void           _gweather_info_request_done (GWeatherInfo *info,
+                                            SoupMessage  *message);
 
 void           ecl2equ                 (gdouble t,
                                         gdouble eclipLon,
diff --git a/libgweather/weather-wx.c b/libgweather/weather-wx.c
index 567e072..2701dce 100644
--- a/libgweather/weather-wx.c
+++ b/libgweather/weather-wx.c
@@ -34,10 +34,11 @@ wx_finish (SoupSession *session, SoupMessage *msg, gpointer data)
     priv = info->priv;
 
     if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
-       g_warning ("Failed to get radar map image: %d %s.\n",
-                  msg->status_code, msg->reason_phrase);
+       if (msg->status_code != SOUP_STATUS_CANCELLED)
+           g_warning ("Failed to get radar map image: %d %s.\n",
+                      msg->status_code, msg->reason_phrase);
        g_object_unref (priv->radar_loader);
-       _gweather_info_request_done (info);
+       _gweather_info_request_done (info, msg);
        return;
     }
 
@@ -51,7 +52,7 @@ wx_finish (SoupSession *session, SoupMessage *msg, gpointer data)
     }
     g_object_unref (priv->radar_loader);
 
-    _gweather_info_request_done (info);
+    _gweather_info_request_done (info, msg);
 }
 
 static void
@@ -103,8 +104,8 @@ wx_start_open (GWeatherInfo *info)
 
     g_signal_connect (msg, "got-chunk", G_CALLBACK (wx_got_chunk), info);
     soup_message_body_set_accumulate (msg->response_body, FALSE);
+    _gweather_info_begin_request (info, msg);
     soup_session_queue_message (priv->session, msg, wx_finish, info);
-    g_free (url);
 
-    priv->requests_pending++;
+    g_free (url);
 }
diff --git a/libgweather/weather-yahoo.c b/libgweather/weather-yahoo.c
index 778169e..a44ae21 100644
--- a/libgweather/weather-yahoo.c
+++ b/libgweather/weather-yahoo.c
@@ -249,14 +249,15 @@ yahoo_finish (SoupSession *session,
 
     if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
        /* forecast data is not really interesting anyway ;) */
-       g_warning ("Failed to get Yahoo! Weather forecast data: %d %s\n",
-                  msg->status_code, msg->reason_phrase);
-       _gweather_info_request_done (info);
+       if (msg->status_code != SOUP_STATUS_CANCELLED)
+           g_warning ("Failed to get Yahoo! Weather forecast data: %d %s\n",
+                      msg->status_code, msg->reason_phrase);
+       _gweather_info_request_done (info, msg);
        return;
     }
 
     parse_forecast_xml (info, msg->response_body);
-    _gweather_info_request_done (info);
+    _gweather_info_request_done (info, msg);
 }
 
 gboolean
@@ -280,10 +281,9 @@ yahoo_start_open (GWeatherInfo *info)
     url = g_strdup_printf("http://weather.yahooapis.com/forecastrss?w=%s&u=f";, loc->yahoo_id);
 
     message = soup_message_new ("GET", url);
+    _gweather_info_begin_request (info, message);
     soup_session_queue_message (priv->session, message, yahoo_finish, info);
 
-    priv->requests_pending++;
-
     g_free (url);
 
     return TRUE;
diff --git a/libgweather/weather-yrno.c b/libgweather/weather-yrno.c
index 6f07e16..05d43a9 100644
--- a/libgweather/weather-yrno.c
+++ b/libgweather/weather-yrno.c
@@ -463,14 +463,15 @@ yrno_finish_old (SoupSession *session,
 
     if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
        /* forecast data is not really interesting anyway ;) */
-       g_message ("Failed to get Yr.no forecast data: %d %s\n",
-                  msg->status_code, msg->reason_phrase);
-       _gweather_info_request_done (info);
+       if (msg->status_code != SOUP_STATUS_CANCELLED)
+           g_message ("Failed to get Yr.no forecast data: %d %s\n",
+                      msg->status_code, msg->reason_phrase);
+       _gweather_info_request_done (info, msg);
        return;
     }
 
     parse_forecast_xml_old (info, msg->response_body);
-    _gweather_info_request_done (info);
+    _gweather_info_request_done (info, msg);
 }
 
 static gboolean
@@ -487,10 +488,9 @@ yrno_start_open_old (GWeatherInfo *info)
        return FALSE;
 
     message = soup_message_new ("GET", url);
+    _gweather_info_begin_request (info, message);
     soup_session_queue_message (priv->session, message, yrno_finish_old, info);
 
-    priv->requests_pending++;
-
     g_free (url);
 
     return TRUE;
@@ -505,15 +505,16 @@ yrno_finish_new (SoupSession *session,
 
     if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
        /* forecast data is not really interesting anyway ;) */
-       g_message ("Failed to get Yr.no forecast data: %d %s\n",
-                  msg->status_code, msg->reason_phrase);
-       _gweather_info_request_done (info);
+       if (msg->status_code != SOUP_STATUS_CANCELLED)
+           g_message ("Failed to get Yr.no forecast data: %d %s\n",
+                      msg->status_code, msg->reason_phrase);
+       _gweather_info_request_done (info, msg);
        return;
     }
 
     parse_forecast_xml_new (info, msg->response_body);
 
-    _gweather_info_request_done (info);
+    _gweather_info_request_done (info, msg);
 }
 
 static gboolean
@@ -539,10 +540,9 @@ yrno_start_open_new (GWeatherInfo *info)
     url = g_strdup_printf("http://api.yr.no/weatherapi/locationforecast/1.8/?lat=%s;lon=%s";, latstr, lonstr);
 
     message = soup_message_new ("GET", url);
+    _gweather_info_begin_request (info, message);
     soup_session_queue_message (priv->session, message, yrno_finish_new, info);
 
-    priv->requests_pending++;
-
     g_free (url);
 
     return TRUE;
diff --git a/libgweather/weather.c b/libgweather/weather.c
index b0d40d1..4cca36b 100644
--- a/libgweather/weather.c
+++ b/libgweather/weather.c
@@ -226,9 +226,21 @@ requests_init (GWeatherInfo *info)
 }
 
 void
-_gweather_info_request_done (GWeatherInfo *info)
+_gweather_info_begin_request (GWeatherInfo *info,
+                             SoupMessage  *message)
 {
-    if (!--info->priv->requests_pending)
+    info->priv->requests_pending = g_slist_prepend (info->priv->requests_pending, message);
+    g_object_ref (message);
+}
+
+void
+_gweather_info_request_done (GWeatherInfo *info,
+                            SoupMessage  *message)
+{
+    info->priv->requests_pending = g_slist_remove (info->priv->requests_pending, message);
+    g_object_ref (message);
+
+    if (info->priv->requests_pending == NULL)
         g_signal_emit (info, gweather_info_signals[SIGNAL_UPDATED], 0);
 }
 
@@ -423,7 +435,7 @@ settings_changed_cb (GSettings    *settings,
        Otherwise just wait for the update that will happen at
        the end
     */
-    if (priv->requests_pending == 0)
+    if (priv->requests_pending == NULL)
         g_signal_emit (info, gweather_info_signals[SIGNAL_UPDATED], 0);
 }
 
@@ -589,12 +601,25 @@ gweather_info_update (GWeatherInfo *info)
 void
 gweather_info_abort (GWeatherInfo *info)
 {
+    GSList *list, *iter;
+    GSList dummy = { NULL, NULL };
+
     g_return_if_fail (GWEATHER_IS_INFO (info));
 
-    if (info->priv->session) {
-       soup_session_abort (info->priv->session);
-       info->priv->requests_pending = 0;
+    if (info->priv->session == NULL) {
+       g_assert (info->priv->requests_pending == NULL);
+       return;
     }
+
+    list = info->priv->requests_pending;
+    /* to block updated signals */
+    info->priv->requests_pending = &dummy;
+
+    for (iter = list; iter; iter = iter->next)
+       soup_session_cancel_message (info->priv->session, iter->data, SOUP_STATUS_CANCELLED);
+    g_slist_free (list);
+
+    info->priv->requests_pending = NULL;
 }
 
 static void


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