summaryrefslogtreecommitdiff
path: root/libsoup/soup-session-feature.c
diff options
context:
space:
mode:
authorClaudio Saavedra <csaavedra@igalia.com>2019-01-18 17:32:58 +0200
committerClaudio Saavedra <csaavedra@igalia.com>2019-01-18 17:47:43 +0200
commitcedfc390fd4d17b930b33f523b1f2c1d97e718c0 (patch)
tree4219e313a07268a5b2580bd2a1fc23d27e139150 /libsoup/soup-session-feature.c
parent88fcafd9390ebc14a2b4cfbc253c96cf4d712817 (diff)
downloadlibsoup-cedfc390fd4d17b930b33f523b1f2c1d97e718c0.tar.gz
SoupSessionFeature: Keep features alive until all messages have been unqueued
Features can be removed at any point from a session, and if they are removed while there are messages in the queue, it is possible for callbacks connected to the message signals to be called after the feature has been disposed. Adding a reference in request_queue() and removing it in request_enqueue() ensures that the feature will not be disposed too early. Add a test case for the SoupCookieJar feature that reproduces this crash. Fixes #130
Diffstat (limited to 'libsoup/soup-session-feature.c')
-rw-r--r--libsoup/soup-session-feature.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/libsoup/soup-session-feature.c b/libsoup/soup-session-feature.c
index d8bb10a3..12716a62 100644
--- a/libsoup/soup-session-feature.c
+++ b/libsoup/soup-session-feature.c
@@ -66,8 +66,11 @@ request_queued (SoupSession *session, SoupMessage *msg, gpointer feature)
if (soup_message_disables_feature (msg, feature))
return;
- SOUP_SESSION_FEATURE_GET_CLASS (feature)->
- request_queued (feature, session, msg);
+ g_object_ref (feature);
+ if (SOUP_SESSION_FEATURE_GET_CLASS (feature)->request_queued) {
+ SOUP_SESSION_FEATURE_GET_CLASS (feature)->
+ request_queued (feature, session, msg);
+ }
}
static void
@@ -87,8 +90,11 @@ request_unqueued (SoupSession *session, SoupMessage *msg, gpointer feature)
if (soup_message_disables_feature (msg, feature))
return;
- SOUP_SESSION_FEATURE_GET_CLASS (feature)->
- request_unqueued (feature, session, msg);
+ if (SOUP_SESSION_FEATURE_GET_CLASS (feature)->request_unqueued) {
+ SOUP_SESSION_FEATURE_GET_CLASS (feature)->
+ request_unqueued (feature, session, msg);
+ }
+ g_object_unref (feature);
}
static void
@@ -97,20 +103,16 @@ soup_session_feature_real_attach (SoupSessionFeature *feature, SoupSession *sess
g_object_weak_ref (G_OBJECT (session),
weak_notify_unref, g_object_ref (feature));
- if (SOUP_SESSION_FEATURE_GET_CLASS (feature)->request_queued) {
- g_signal_connect (session, "request_queued",
- G_CALLBACK (request_queued), feature);
- }
+ g_signal_connect (session, "request_queued",
+ G_CALLBACK (request_queued), feature);
if (SOUP_SESSION_FEATURE_GET_CLASS (feature)->request_started) {
g_signal_connect (session, "request_started",
G_CALLBACK (request_started), feature);
}
- if (SOUP_SESSION_FEATURE_GET_CLASS (feature)->request_unqueued) {
- g_signal_connect (session, "request_unqueued",
- G_CALLBACK (request_unqueued), feature);
- }
+ g_signal_connect (session, "request_unqueued",
+ G_CALLBACK (request_unqueued), feature);
}
void