diff options
author | Claudio Saavedra <csaavedra@igalia.com> | 2019-01-18 17:32:58 +0200 |
---|---|---|
committer | Claudio Saavedra <csaavedra@igalia.com> | 2019-01-18 17:47:43 +0200 |
commit | cedfc390fd4d17b930b33f523b1f2c1d97e718c0 (patch) | |
tree | 4219e313a07268a5b2580bd2a1fc23d27e139150 /libsoup/soup-session-feature.c | |
parent | 88fcafd9390ebc14a2b4cfbc253c96cf4d712817 (diff) | |
download | libsoup-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.c | 26 |
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 |