[evolution-data-server/wip/mcrha/soup3] Make sure GInputStream received from libsoup3 is consumed in the same thread
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/wip/mcrha/soup3] Make sure GInputStream received from libsoup3 is consumed in the same thread
- Date: Thu, 5 May 2022 16:30:58 +0000 (UTC)
commit f747a4ea7c76bafbf7336d3935cbf0ec0295e861
Author: Milan Crha <mcrha redhat com>
Date: Thu May 5 18:30:11 2022 +0200
Make sure GInputStream received from libsoup3 is consumed in the same thread
src/calendar/backends/http/e-cal-backend-http.c | 48 +++++++++++--------------
src/libedataserver/e-soup-session.c | 8 +++++
2 files changed, 28 insertions(+), 28 deletions(-)
---
diff --git a/src/calendar/backends/http/e-cal-backend-http.c b/src/calendar/backends/http/e-cal-backend-http.c
index 34ba531e5..246334aa2 100644
--- a/src/calendar/backends/http/e-cal-backend-http.c
+++ b/src/calendar/backends/http/e-cal-backend-http.c
@@ -37,7 +37,7 @@ struct _ECalBackendHttpPrivate {
ESoupSession *session;
SoupMessage *message;
- GInputStream *input_stream;
+ gchar *icalstring;
GRecMutex conn_lock;
GHashTable *components; /* gchar *uid ~> ICalComponent * */
gint64 hsts_until_time;
@@ -202,14 +202,14 @@ ecb_http_connect_sync (ECalMetaBackend *meta_backend,
g_rec_mutex_lock (&cbhttp->priv->conn_lock);
- if (cbhttp->priv->message && cbhttp->priv->input_stream) {
+ if (cbhttp->priv->message && cbhttp->priv->icalstring) {
g_rec_mutex_unlock (&cbhttp->priv->conn_lock);
return TRUE;
}
source = e_backend_get_source (E_BACKEND (meta_backend));
- g_clear_object (&cbhttp->priv->input_stream);
+ g_clear_pointer (&cbhttp->priv->icalstring, g_free);
g_clear_object (&cbhttp->priv->message);
uri = ecb_http_dup_uri (cbhttp);
@@ -296,15 +296,19 @@ ecb_http_connect_sync (ECalMetaBackend *meta_backend,
uri, local_error ? local_error->message : _("Unknown error"));
}
+ if (success) {
+ cbhttp->priv->icalstring = ecb_http_read_stream_sync (input_stream,
+ soup_message_headers_get_content_length (soup_message_get_response_headers
(message)), cancellable, error);
+ success = cbhttp->priv->icalstring != NULL;
+ }
+
if (success) {
cbhttp->priv->message = message;
- cbhttp->priv->input_stream = input_stream;
cbhttp->priv->hsts_until_time = ecb_http_extract_hsts_until_time (cbhttp);
*out_auth_result = E_SOURCE_AUTHENTICATION_ACCEPTED;
} else {
g_clear_object (&message);
- g_clear_object (&input_stream);
if (*out_auth_result != E_SOURCE_AUTHENTICATION_REQUIRED &&
*out_auth_result != E_SOURCE_AUTHENTICATION_REJECTED)
@@ -312,6 +316,7 @@ ecb_http_connect_sync (ECalMetaBackend *meta_backend,
}
g_rec_mutex_unlock (&cbhttp->priv->conn_lock);
+ g_clear_object (&input_stream);
g_clear_error (&local_error);
g_free (uri);
@@ -332,7 +337,7 @@ ecb_http_disconnect_sync (ECalMetaBackend *meta_backend,
g_rec_mutex_lock (&cbhttp->priv->conn_lock);
- g_clear_object (&cbhttp->priv->input_stream);
+ g_clear_pointer (&cbhttp->priv->icalstring, g_free);
g_clear_object (&cbhttp->priv->message);
if (cbhttp->priv->session)
@@ -361,7 +366,6 @@ ecb_http_get_changes_sync (ECalMetaBackend *meta_backend,
GError **error)
{
ECalBackendHttp *cbhttp;
- gchar *icalstring;
ICalCompIter *iter = NULL;
ICalComponent *maincomp, *subcomp;
ICalComponentKind backend_kind;
@@ -380,7 +384,7 @@ ecb_http_get_changes_sync (ECalMetaBackend *meta_backend,
g_rec_mutex_lock (&cbhttp->priv->conn_lock);
- if (!cbhttp->priv->message || !cbhttp->priv->input_stream) {
+ if (!cbhttp->priv->message || !cbhttp->priv->icalstring) {
g_rec_mutex_unlock (&cbhttp->priv->conn_lock);
g_propagate_error (error, EC_ERROR (E_CLIENT_ERROR_REPOSITORY_OFFLINE));
return FALSE;
@@ -408,27 +412,15 @@ ecb_http_get_changes_sync (ECalMetaBackend *meta_backend,
*out_new_sync_tag = g_strdup (new_etag);
- icalstring = ecb_http_read_stream_sync (cbhttp->priv->input_stream,
- soup_message_headers_get_content_length (soup_message_get_response_headers
(cbhttp->priv->message)), cancellable, error);
-
g_rec_mutex_unlock (&cbhttp->priv->conn_lock);
- if (!icalstring) {
- /* The error is already set */
- e_cal_meta_backend_empty_cache_sync (meta_backend, cancellable, NULL);
- ecb_http_disconnect_sync (meta_backend, cancellable, NULL);
- return FALSE;
- }
-
/* Skip the UTF-8 marker at the beginning of the string */
- if (((guchar) icalstring[0]) == 0xEF &&
- ((guchar) icalstring[1]) == 0xBB &&
- ((guchar) icalstring[2]) == 0xBF)
- maincomp = i_cal_parser_parse_string (icalstring + 3);
+ if (((guchar) cbhttp->priv->icalstring[0]) == 0xEF &&
+ ((guchar) cbhttp->priv->icalstring[1]) == 0xBB &&
+ ((guchar) cbhttp->priv->icalstring[2]) == 0xBF)
+ maincomp = i_cal_parser_parse_string (cbhttp->priv->icalstring + 3);
else
- maincomp = i_cal_parser_parse_string (icalstring);
-
- g_free (icalstring);
+ maincomp = i_cal_parser_parse_string (cbhttp->priv->icalstring);
if (!maincomp) {
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Bad file format."));
@@ -537,8 +529,8 @@ ecb_http_get_changes_sync (ECalMetaBackend *meta_backend,
g_object_unref (maincomp);
}
- if (!success)
- ecb_http_disconnect_sync (meta_backend, cancellable, NULL);
+ /* Always disconnect, to free the resources needed to download the iCalendar file */
+ ecb_http_disconnect_sync (meta_backend, cancellable, NULL);
return success;
}
@@ -675,7 +667,7 @@ e_cal_backend_http_dispose (GObject *object)
g_rec_mutex_lock (&cbhttp->priv->conn_lock);
g_clear_object (&cbhttp->priv->message);
- g_clear_object (&cbhttp->priv->input_stream);
+ g_clear_pointer (&cbhttp->priv->icalstring, g_free);
if (cbhttp->priv->session)
soup_session_abort (SOUP_SESSION (cbhttp->priv->session));
diff --git a/src/libedataserver/e-soup-session.c b/src/libedataserver/e-soup-session.c
index d27640905..80b11b3dd 100644
--- a/src/libedataserver/e-soup-session.c
+++ b/src/libedataserver/e-soup-session.c
@@ -1288,6 +1288,10 @@ e_soup_session_send_message (ESoupSession *session,
* The optional @out_certificate_pem and @out_certificate_errors are set,
* when provided, only if the operation failed with a TLS/SSL error.
*
+ * Make sure the #GInputStream is read and freed from the same thread,
+ * and with the same thread default main context, which this function
+ * was called from, otherwise it can break libsoup3.
+ *
* Returns: (transfer full) (nullable): a #GInputStream for reading the response body, or %NULL on error
*
* Since: 3.48
@@ -1345,6 +1349,10 @@ e_soup_session_send_message_finish (ESoupSession *session,
* e_soup_session_check_result() to verify that the receive had
* been finished properly.
*
+ * Make sure the #GInputStream is read and freed from the same thread,
+ * and with the same thread default main context, which this function
+ * was called from, otherwise it can break libsoup3.
+ *
* Returns: (transfer full): A newly allocated #GInputStream,
* that can be used to read from the URI pointed to by @message.
* Free it with g_object_unref(), when no longer needed.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]