[evolution-data-server/wip/mcrha/soup3] ESoupSession: Add a lock around the SoupSession usage
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/wip/mcrha/soup3] ESoupSession: Add a lock around the SoupSession usage
- Date: Tue, 11 Jan 2022 13:50:05 +0000 (UTC)
commit 719609870e3377f6f0cc4e96b61e0e31bf2caa8e
Author: Milan Crha <mcrha redhat com>
Date: Tue Jan 11 14:49:02 2022 +0100
ESoupSession: Add a lock around the SoupSession usage
The SoupSession in libsoup3 is completely thread unsafe.
src/libedataserver/e-soup-session.c | 37 +++++++++++++++++++++++++++++++++++--
1 file changed, 35 insertions(+), 2 deletions(-)
---
diff --git a/src/libedataserver/e-soup-session.c b/src/libedataserver/e-soup-session.c
index 8cf4af15e..286140eb4 100644
--- a/src/libedataserver/e-soup-session.c
+++ b/src/libedataserver/e-soup-session.c
@@ -43,6 +43,7 @@ G_DEFINE_QUARK (e-soup-session-error-quark, e_soup_session_error)
struct _ESoupSessionPrivate {
GMutex property_lock;
+ GRecMutex session_lock; /* libsoup3 has no thread safety */
ESource *source;
ENamedParameters *credentials;
@@ -80,6 +81,8 @@ e_soup_session_ensure_auth_usage (ESoupSession *session,
g_return_if_fail (E_IS_SOUP_SESSION (session));
g_return_if_fail (SOUP_IS_AUTH (soup_auth));
+ g_rec_mutex_lock (&session->priv->session_lock);
+
feature = soup_session_get_feature (SOUP_SESSION (session), SOUP_TYPE_AUTH_MANAGER);
auth_type = G_OBJECT_TYPE (soup_auth);
@@ -123,6 +126,8 @@ e_soup_session_ensure_auth_usage (ESoupSession *session,
soup_auth_manager_clear_cached_credentials (auth_manager);
soup_auth_manager_use_auth (auth_manager, g_uri, soup_auth);
+ g_rec_mutex_unlock (&session->priv->session_lock);
+
if (!in_g_uri)
g_uri_unref (g_uri);
}
@@ -307,9 +312,13 @@ e_soup_session_maybe_prepare_auth (ESoupSession *session,
} else if (g_strcmp0 (auth_method, "GSSAPI") == 0 && soup_auth_negotiate_supported ()) {
SoupSession *soup_session = SOUP_SESSION (session);
+ g_rec_mutex_lock (&session->priv->session_lock);
+
if (!soup_session_get_feature (soup_session, SOUP_TYPE_AUTH_NEGOTIATE))
soup_session_add_feature_by_type (soup_session, SOUP_TYPE_AUTH_NEGOTIATE);
soup_session_remove_feature_by_type (soup_session, SOUP_TYPE_AUTH_BASIC);
+
+ g_rec_mutex_unlock (&session->priv->session_lock);
} else if (user && *user) {
/* Default to Basic authentication when user is filled */
success = e_soup_session_maybe_prepare_basic_auth (session, g_uri, message, user,
credentials, cancellable, error);
@@ -468,6 +477,7 @@ e_soup_session_finalize (GObject *object)
g_clear_pointer (&session->priv->ssl_certificate_pem, g_free);
g_mutex_clear (&session->priv->property_lock);
+ g_rec_mutex_clear (&session->priv->session_lock);
/* Chain up to parent's method. */
G_OBJECT_CLASS (e_soup_session_parent_class)->finalize (object);
@@ -531,6 +541,7 @@ e_soup_session_init (ESoupSession *session)
session->priv->auth_prefilled = FALSE;
g_mutex_init (&session->priv->property_lock);
+ g_rec_mutex_init (&session->priv->session_lock);
g_object_set (
G_OBJECT (session),
@@ -591,11 +602,15 @@ e_soup_session_setup_logging (ESoupSession *session,
g_return_if_fail (E_IS_SOUP_SESSION (session));
+ g_rec_mutex_lock (&session->priv->session_lock);
+
soup_session_remove_feature_by_type (SOUP_SESSION (session), SOUP_TYPE_LOGGER);
session->priv->log_level = SOUP_LOGGER_LOG_NONE;
- if (!logging_level)
+ if (!logging_level) {
+ g_rec_mutex_unlock (&session->priv->session_lock);
return;
+ }
if (g_ascii_strcasecmp (logging_level, "all") == 0 ||
g_ascii_strcasecmp (logging_level, "body") == 0 ||
@@ -605,12 +620,16 @@ e_soup_session_setup_logging (ESoupSession *session,
session->priv->log_level = SOUP_LOGGER_LOG_HEADERS;
else if (g_ascii_strcasecmp (logging_level, "min") == 0)
session->priv->log_level = SOUP_LOGGER_LOG_MINIMAL;
- else
+ else {
+ g_rec_mutex_unlock (&session->priv->session_lock);
return;
+ }
logger = soup_logger_new (session->priv->log_level);
soup_session_add_feature (SOUP_SESSION (session), SOUP_SESSION_FEATURE (logger));
g_object_unref (logger);
+
+ g_rec_mutex_unlock (&session->priv->session_lock);
}
/**
@@ -1141,6 +1160,7 @@ e_soup_session_send_message_ready_cb (GObject *source_object,
gpointer user_data)
{
AsyncSendData *asd = user_data;
+ ESoupSession *esession;
SoupSession *session;
GInputStream *input_stream;
GError *local_error = NULL;
@@ -1148,6 +1168,9 @@ e_soup_session_send_message_ready_cb (GObject *source_object,
g_return_if_fail (asd != NULL);
session = SOUP_SESSION (source_object);
+ esession = E_SOUP_SESSION (session);
+
+ g_rec_mutex_lock (&esession->priv->session_lock);
input_stream = soup_session_send_finish (session, result, &local_error);
@@ -1168,6 +1191,8 @@ e_soup_session_send_message_ready_cb (GObject *source_object,
}
}
+ g_rec_mutex_unlock (&esession->priv->session_lock);
+
if (local_error) {
g_task_return_error (asd->task, local_error);
g_clear_object (&input_stream);
@@ -1220,8 +1245,12 @@ e_soup_session_send_message (ESoupSession *session,
g_task_set_source_tag (asd->task, e_soup_session_send_message);
g_task_set_task_data (asd->task, asd, async_send_data_free);
+ g_rec_mutex_lock (&session->priv->session_lock);
+
soup_session_send_async (SOUP_SESSION (session), message, io_priority, cancellable,
e_soup_session_send_message_ready_cb, asd);
+
+ g_rec_mutex_unlock (&session->priv->session_lock);
}
/**
@@ -1341,8 +1370,12 @@ e_soup_session_send_message_sync (ESoupSession *session,
return NULL;
}
+ g_rec_mutex_lock (&session->priv->session_lock);
+
input_stream = soup_session_send (SOUP_SESSION (session), message, cancellable, &local_error);
+ g_rec_mutex_unlock (&session->priv->session_lock);
+
if (input_stream) {
if (SOUP_STATUS_IS_REDIRECTION (soup_message_get_status (message))) {
/* libsoup uses 20, but the constant is not in any public header */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]