[libgweather] GWeatherInfo: don't abort the entire SoupSession



commit 356a5889a51dc3077dab4a3be4b0ac3ce62ce8d9
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 06841b9..065fd6c 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
@@ -442,10 +443,9 @@ owm_start_open (GWeatherInfo *info)
 #undef TEMPLATE
 
     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 f81c228..09c7e99 100644
--- a/libgweather/weather-priv.h
+++ b/libgweather/weather-priv.h
@@ -134,7 +134,7 @@ struct _GWeatherInfoPrivate {
     GdkPixbufLoader *radar_loader;
     GdkPixbufAnimation *radar;
     SoupSession *session;
-    gint requests_pending;
+    GSList *requests_pending;
 };
 
 /* Values common to the parsing source files */
@@ -191,7 +191,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 3b42a48..f7db931 100644
--- a/libgweather/weather-yrno.c
+++ b/libgweather/weather-yrno.c
@@ -458,14 +458,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
@@ -482,10 +483,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;
@@ -500,15 +500,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
@@ -534,10 +535,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 d9b7807..9d97cac 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]