diff --git a/ext/soup/gstsouphttpsrc.c b/ext/soup/gstsouphttpsrc.c
index 3011058..c1abf9e 100644
--- a/ext/soup/gstsouphttpsrc.c
+++ b/ext/soup/gstsouphttpsrc.c
@@ -1232,8 +1232,11 @@ gst_soup_http_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
         break;
     }
 
-    if (src->ret == GST_FLOW_CUSTOM_ERROR)
+    if (src->ret == GST_FLOW_CUSTOM_ERROR) {
+      g_main_context_push_thread_default (src->context);
       g_main_loop_run (src->loop);
+      g_main_context_pop_thread_default (src->context);
+    }
   } while (src->ret == GST_FLOW_CUSTOM_ERROR);
 
   if (src->ret == GST_FLOW_CUSTOM_ERROR)
@@ -1293,6 +1296,13 @@ gst_soup_http_src_start (GstBaseSrc * bsrc)
 }
 
 static gboolean
+dummy_idle_cb (gpointer data)
+{
+    (void) data;
+    return FALSE /* Idle source is removed */;
+}
+
+static gboolean
 gst_soup_http_src_stop (GstBaseSrc * bsrc)
 {
   GstSoupHTTPSrc *src;
@@ -1301,6 +1311,24 @@ gst_soup_http_src_stop (GstBaseSrc * bsrc)
   GST_DEBUG_OBJECT (src, "stop()");
   gst_soup_http_src_session_close (src);
   if (src->loop) {
+    g_main_loop_quit (src->loop);
+
+    {
+      /* Iterating the main context to give GIO cancellables a chance
+       * to initiate cleanups. Wihout this, resources allocated by
+       * libsoup for the connection are not released and socket fd is
+       * leaked. */
+      GSource * const idle_source = g_idle_source_new ();
+      /* Suppressing "idle souce without callback" warning */
+      g_source_set_callback (idle_source, dummy_idle_cb, NULL, NULL);
+      g_source_attach (idle_source, src->context);
+      /* Acquiring the context. Idle source guarantees that we'll not block. */
+      g_main_context_iteration (src->context, TRUE);
+      /* Ensuring that there's no unhandled pending events left. */
+      while (g_main_context_iteration (src->context, FALSE));
+      g_source_unref (idle_source);
+    }
+
     g_main_loop_unref (src->loop);
     g_main_context_unref (src->context);
     src->loop = NULL;
