summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/network/soup/ResourceHandleSoup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/network/soup/ResourceHandleSoup.cpp')
-rw-r--r--WebCore/platform/network/soup/ResourceHandleSoup.cpp63
1 files changed, 39 insertions, 24 deletions
diff --git a/WebCore/platform/network/soup/ResourceHandleSoup.cpp b/WebCore/platform/network/soup/ResourceHandleSoup.cpp
index 4a22d8a..280fc38 100644
--- a/WebCore/platform/network/soup/ResourceHandleSoup.cpp
+++ b/WebCore/platform/network/soup/ResourceHandleSoup.cpp
@@ -118,7 +118,7 @@ void WebCoreSynchronousLoader::run()
g_main_loop_run(m_mainLoop);
}
-static void cleanupGioOperation(ResourceHandleInternal* handle);
+static void cleanupGioOperation(ResourceHandle* handle, bool isDestroying);
static bool startData(ResourceHandle* handle, String urlString);
static bool startGio(ResourceHandle* handle, KURL url);
@@ -129,8 +129,6 @@ ResourceHandleInternal::~ResourceHandleInternal()
m_msg = 0;
}
- cleanupGioOperation(this);
-
if (m_idleHandler) {
g_source_remove(m_idleHandler);
m_idleHandler = 0;
@@ -142,6 +140,8 @@ ResourceHandle::~ResourceHandle()
if (d->m_msg)
g_signal_handlers_disconnect_matched(d->m_msg, G_SIGNAL_MATCH_DATA,
0, 0, 0, 0, this);
+
+ cleanupGioOperation(this, true);
}
static void fillResponseFromMessage(SoupMessage* msg, ResourceResponse* response)
@@ -276,7 +276,7 @@ static void gotChunkCallback(SoupMessage* msg, SoupBuffer* chunk, gpointer data)
// Doesn't get called for redirects.
static void finishedCallback(SoupSession *session, SoupMessage* msg, gpointer data)
{
- RefPtr<ResourceHandle>handle = adoptRef(static_cast<ResourceHandle*>(data));
+ RefPtr<ResourceHandle> handle = adoptRef(static_cast<ResourceHandle*>(data));
// TODO: maybe we should run this code even if there's no client?
if (!handle)
return;
@@ -625,8 +625,10 @@ void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, S
// GIO-based loader
-static void cleanupGioOperation(ResourceHandleInternal* d)
+static void cleanupGioOperation(ResourceHandle* handle, bool isDestroying = false)
{
+ ResourceHandleInternal* d = handle->getInternal();
+
if (d->m_gfile) {
g_object_set_data(G_OBJECT(d->m_gfile), "webkit-resource", 0);
g_object_unref(d->m_gfile);
@@ -648,11 +650,14 @@ static void cleanupGioOperation(ResourceHandleInternal* d)
g_free(d->m_buffer);
d->m_buffer = 0;
}
+
+ if (!isDestroying)
+ handle->deref();
}
static void closeCallback(GObject* source, GAsyncResult* res, gpointer)
{
- ResourceHandle* handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
+ RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
if (!handle)
return;
@@ -660,13 +665,12 @@ static void closeCallback(GObject* source, GAsyncResult* res, gpointer)
ResourceHandleClient* client = handle->client();
g_input_stream_close_finish(d->m_inputStream, res, 0);
- cleanupGioOperation(d);
- client->didFinishLoading(handle);
+ cleanupGioOperation(handle.get());
+ client->didFinishLoading(handle.get());
}
static void readCallback(GObject* source, GAsyncResult* res, gpointer)
{
- // didReceiveData may cancel the load, which may release the last reference.
RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
if (!handle)
return;
@@ -675,7 +679,7 @@ static void readCallback(GObject* source, GAsyncResult* res, gpointer)
ResourceHandleClient* client = handle->client();
if (d->m_cancelled || !client) {
- cleanupGioOperation(d);
+ cleanupGioOperation(handle.get());
return;
}
@@ -690,7 +694,7 @@ static void readCallback(GObject* source, GAsyncResult* res, gpointer)
error ? String::fromUTF8(error->message) : String());
g_free(uri);
g_error_free(error);
- cleanupGioOperation(d);
+ cleanupGioOperation(handle.get());
client->didFail(handle.get(), resourceError);
return;
}
@@ -704,8 +708,9 @@ static void readCallback(GObject* source, GAsyncResult* res, gpointer)
d->m_total += bytesRead;
client->didReceiveData(handle.get(), d->m_buffer, bytesRead, d->m_total);
+ // didReceiveData may cancel the load, which may release the last reference.
if (d->m_cancelled) {
- cleanupGioOperation(d);
+ cleanupGioOperation(handle.get());
return;
}
@@ -716,7 +721,7 @@ static void readCallback(GObject* source, GAsyncResult* res, gpointer)
static void openCallback(GObject* source, GAsyncResult* res, gpointer)
{
- ResourceHandle* handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
+ RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
if (!handle)
return;
@@ -724,7 +729,7 @@ static void openCallback(GObject* source, GAsyncResult* res, gpointer)
ResourceHandleClient* client = handle->client();
if (d->m_cancelled || !client) {
- cleanupGioOperation(d);
+ cleanupGioOperation(handle.get());
return;
}
@@ -738,8 +743,8 @@ static void openCallback(GObject* source, GAsyncResult* res, gpointer)
error ? String::fromUTF8(error->message) : String());
g_free(uri);
g_error_free(error);
- cleanupGioOperation(d);
- client->didFail(handle, resourceError);
+ cleanupGioOperation(handle.get());
+ client->didFail(handle.get(), resourceError);
return;
}
@@ -747,7 +752,8 @@ static void openCallback(GObject* source, GAsyncResult* res, gpointer)
d->m_bufferSize = 8192;
d->m_buffer = static_cast<char*>(g_malloc(d->m_bufferSize));
d->m_total = 0;
- g_object_set_data(G_OBJECT(d->m_inputStream), "webkit-resource", handle);
+
+ g_object_set_data(G_OBJECT(d->m_inputStream), "webkit-resource", handle.get());
g_input_stream_read_async(d->m_inputStream, d->m_buffer, d->m_bufferSize,
G_PRIORITY_DEFAULT, d->m_cancellable,
readCallback, 0);
@@ -755,7 +761,7 @@ static void openCallback(GObject* source, GAsyncResult* res, gpointer)
static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer)
{
- ResourceHandle* handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
+ RefPtr<ResourceHandle> handle = static_cast<ResourceHandle*>(g_object_get_data(source, "webkit-resource"));
if (!handle)
return;
@@ -763,7 +769,7 @@ static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer)
ResourceHandleClient* client = handle->client();
if (d->m_cancelled) {
- cleanupGioOperation(d);
+ cleanupGioOperation(handle.get());
return;
}
@@ -790,8 +796,8 @@ static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer)
error ? String::fromUTF8(error->message) : String());
g_free(uri);
g_error_free(error);
- cleanupGioOperation(d);
- client->didFail(handle, resourceError);
+ cleanupGioOperation(handle.get());
+ client->didFail(handle.get(), resourceError);
return;
}
@@ -804,8 +810,8 @@ static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer)
uri,
String());
g_free(uri);
- cleanupGioOperation(d);
- client->didFail(handle, resourceError);
+ cleanupGioOperation(handle.get());
+ client->didFail(handle.get(), resourceError);
return;
}
@@ -816,7 +822,12 @@ static void queryInfoCallback(GObject* source, GAsyncResult* res, gpointer)
g_file_info_get_modification_time(info, &tv);
response.setLastModifiedDate(tv.tv_sec);
- client->didReceiveResponse(handle, response);
+ client->didReceiveResponse(handle.get(), response);
+
+ if (d->m_cancelled) {
+ cleanupGioOperation(handle.get());
+ return;
+ }
g_file_read_async(d->m_gfile, G_PRIORITY_DEFAULT, d->m_cancellable,
openCallback, 0);
@@ -852,6 +863,10 @@ static bool startGio(ResourceHandle* handle, KURL url)
#endif
d->m_gfile = g_file_new_for_uri(url.string().utf8().data());
g_object_set_data(G_OBJECT(d->m_gfile), "webkit-resource", handle);
+
+ // balanced by a deref() in cleanupGioOperation, which should always run
+ handle->ref();
+
d->m_cancellable = g_cancellable_new();
g_file_query_info_async(d->m_gfile,
G_FILE_ATTRIBUTE_STANDARD_TYPE ","