summaryrefslogtreecommitdiffstats
path: root/WebKit/android/WebCoreSupport
diff options
context:
space:
mode:
authorIain Merrick <husky@google.com>2010-10-28 10:39:47 +0100
committerIain Merrick <husky@google.com>2010-10-28 13:48:51 +0100
commitd4a869207d9c64cff5a8ac08cd9cddf473360504 (patch)
treecdc08af537c0f364c1ff290e70754eb3c7faaabb /WebKit/android/WebCoreSupport
parentbf3f67c4fcfd68df256e5c001c67969997a63e28 (diff)
downloadexternal_webkit-d4a869207d9c64cff5a8ac08cd9cddf473360504.zip
external_webkit-d4a869207d9c64cff5a8ac08cd9cddf473360504.tar.gz
external_webkit-d4a869207d9c64cff5a8ac08cd9cddf473360504.tar.bz2
Use Tasks for WebRequest -> WebUrlLoaderClient callbacks.
We were using some hand-rolled boilerplate for inter-thread communication, with all data packed into the same LoaderData struct. This CL uses the Chromium utility function NewRunnableMethod to pack up the parameters, so the callback methods don't have to be static and can have different parameters. Also using smart pointers wherever possible. Testing: manually verified that both synchronous and asynchronous requests work correctly with no leaks. Will also do stress-testing to check for race conditions. Change-Id: I934a2ee795138f8eee43803a94bb7494ee73031d
Diffstat (limited to 'WebKit/android/WebCoreSupport')
-rw-r--r--WebKit/android/WebCoreSupport/WebRequest.cpp78
-rw-r--r--WebKit/android/WebCoreSupport/WebRequest.h4
-rw-r--r--WebKit/android/WebCoreSupport/WebUrlLoader.h3
-rw-r--r--WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp140
-rw-r--r--WebKit/android/WebCoreSupport/WebUrlLoaderClient.h65
5 files changed, 106 insertions, 184 deletions
diff --git a/WebKit/android/WebCoreSupport/WebRequest.cpp b/WebKit/android/WebCoreSupport/WebRequest.cpp
index ec6dce1..cefd541 100644
--- a/WebKit/android/WebCoreSupport/WebRequest.cpp
+++ b/WebKit/android/WebCoreSupport/WebRequest.cpp
@@ -103,17 +103,21 @@ void WebRequest::finish(bool success)
{
ASSERT(m_loadState < Finished, "called finish on an already finished WebRequest (%d)", m_loadState);
+ // Make sure WebUrlLoaderClient doesn't delete us in the middle of this method.
+ scoped_refptr<WebRequest> guard(this);
+
m_loadState = Finished;
if (success) {
- LoaderData* loaderData = new LoaderData(m_urlLoader);
- m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::didFinishLoading, loaderData);
+ m_urlLoader->maybeCallOnMainThread(NewRunnableMethod(
+ m_urlLoader.get(), &WebUrlLoaderClient::didFinishLoading));
} else {
- WebResponse webResponse(m_request.get());
- LoaderData* loaderData = new LoaderData(m_urlLoader, webResponse);
- m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::didFail, loaderData);
+ OwnPtr<WebResponse> webResponse(new WebResponse(m_request.get()));
+ m_urlLoader->maybeCallOnMainThread(NewRunnableMethod(
+ m_urlLoader.get(), &WebUrlLoaderClient::didFail, webResponse.release()));
}
m_networkBuffer = 0;
m_request = 0;
+ m_urlLoader = 0;
}
void WebRequest::AppendBytesToUpload(WTF::Vector<char>* data)
@@ -170,9 +174,9 @@ void WebRequest::handleAndroidURL()
JNIEnv* env = JSC::Bindings::getJNIEnv();
if (m_inputStream == 0) {
m_loadState = Finished;
- WebResponse webResponse(m_url, "", 0, "", 0);
- LoaderData* loaderData = new LoaderData(m_urlLoader, webResponse);
- m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::didFail, loaderData);
+ OwnPtr<WebResponse> webResponse(new WebResponse(m_url, "", 0, "", 0));
+ m_urlLoader->maybeCallOnMainThread(NewRunnableMethod(
+ m_urlLoader.get(), &WebUrlLoaderClient::didFail, webResponse.release()));
return;
}
@@ -180,9 +184,9 @@ void WebRequest::handleAndroidURL()
FilePath path(m_url);
std::string mimeType("");
net::GetMimeTypeFromFile(path, &mimeType);
- WebResponse webResponse(m_url, mimeType, 0, "", 200);
- LoaderData* loaderResponse = new LoaderData(m_urlLoader, webResponse);
- m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::didReceiveResponse, loaderResponse);
+ OwnPtr<WebResponse> webResponse(new WebResponse(m_url, mimeType, 0, "", 200));
+ m_urlLoader->maybeCallOnMainThread(NewRunnableMethod(
+ m_urlLoader.get(), &WebUrlLoaderClient::didReceiveResponse, webResponse.release()));
int size = 0;
jclass bridgeClass = env->FindClass("android/webkit/BrowserFrame");
@@ -196,14 +200,12 @@ void WebRequest::handleAndroidURL()
// data is deleted in WebUrlLoaderClient::didReceiveAndroidFileData
// data is sent to the webcore thread
- std::vector<char>* data = new std::vector<char>();
- data->reserve(size);
+ OwnPtr<std::vector<char> > data(new std::vector<char>(size));
env->GetByteArrayRegion(jb, 0, size, (jbyte*)&data->front());
m_loadState = GotData;
- // Passes ownership of data
- LoaderData* loaderData = new LoaderData(m_urlLoader, data, size);
- m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::didReceiveAndroidFileData, loaderData);
+ m_urlLoader->maybeCallOnMainThread(NewRunnableMethod(
+ m_urlLoader.get(), &WebUrlLoaderClient::didReceiveAndroidFileData, data.release()));
} while (true);
env->DeleteLocalRef(jb);
@@ -214,7 +216,7 @@ void WebRequest::handleAndroidURL()
void WebRequest::handleDataURL(GURL url)
{
- OwnPtr<std::string*> data(new std::string);
+ OwnPtr<std::string> data(new std::string);
std::string mimeType;
std::string charset;
@@ -222,14 +224,14 @@ void WebRequest::handleDataURL(GURL url)
// PopulateURLResponse from chrome implementation
// weburlloader_impl.cc
m_loadState = Response;
- WebResponse webResponse(url.spec(), mimeType, data->size(), charset, 200);
- LoaderData* loaderResponse = new LoaderData(m_urlLoader, webResponse);
- m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::didReceiveResponse, loaderResponse);
+ OwnPtr<WebResponse> webResponse(new WebResponse(url.spec(), mimeType, data->size(), charset, 200));
+ m_urlLoader->maybeCallOnMainThread(NewRunnableMethod(
+ m_urlLoader.get(), &WebUrlLoaderClient::didReceiveResponse, webResponse.release()));
if (!data->empty()) {
m_loadState = GotData;
- LoaderData* loaderData = new LoaderData(m_urlLoader, data.leakPtr());
- m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::didReceiveDataUrl, loaderData);
+ m_urlLoader->maybeCallOnMainThread(NewRunnableMethod(
+ m_urlLoader.get(), &WebUrlLoaderClient::didReceiveDataUrl, data.release()));
}
} else {
// handle the failed case
@@ -274,10 +276,10 @@ void WebRequest::OnReceivedRedirect(URLRequest* newRequest, const GURL& newUrl,
ASSERT(m_loadState < Response, "Redirect after receiving response");
if (newRequest && newRequest->status().is_success()) {
- WebResponse webResponse(newRequest);
- webResponse.setUrl(newUrl.spec());
- LoaderData* ld = new LoaderData(m_urlLoader, webResponse);
- m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::willSendRequest, ld);
+ OwnPtr<WebResponse> webResponse(new WebResponse(newRequest));
+ webResponse->setUrl(newUrl.spec());
+ m_urlLoader->maybeCallOnMainThread(NewRunnableMethod(
+ m_urlLoader.get(), &WebUrlLoaderClient::willSendRequest, webResponse.release()));
} else {
// why would this happen? And what to do?
}
@@ -297,9 +299,9 @@ void WebRequest::OnAuthRequired(URLRequest* request, net::AuthChallengeInfo* aut
{
ASSERT(m_loadState == Started, "OnAuthRequired called on a WebRequest not in STARTED state (state=%d)", m_loadState);
- LoaderData* ld = new LoaderData(m_urlLoader);
- ld->authChallengeInfo = authInfo;
- m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::authRequired, ld);
+ scoped_refptr<net::AuthChallengeInfo> authInfoPtr(authInfo);
+ m_urlLoader->maybeCallOnMainThread(NewRunnableMethod(
+ m_urlLoader.get(), &WebUrlLoaderClient::authRequired, authInfoPtr));
}
// After calling Start(), the delegate will receive an OnResponseStarted
@@ -314,9 +316,9 @@ void WebRequest::OnResponseStarted(URLRequest* request)
m_loadState = Response;
if (request && request->status().is_success()) {
- WebResponse webResponse(request);
- LoaderData* loaderData = new LoaderData(m_urlLoader, webResponse);
- m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::didReceiveResponse, loaderData);
+ OwnPtr<WebResponse> webResponse(new WebResponse(request));
+ m_urlLoader->maybeCallOnMainThread(NewRunnableMethod(
+ m_urlLoader.get(), &WebUrlLoaderClient::didReceiveResponse, webResponse.release()));
// Start reading the response
startReading();
@@ -367,10 +369,8 @@ void WebRequest::startReading()
m_loadState = GotData;
// Read ok, forward buffer to webcore
- m_networkBuffer->AddRef();
- LoaderData* loaderData = new LoaderData(m_urlLoader, m_networkBuffer.get(), bytesRead);
- m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::didReceiveData, loaderData);
- // m_networkBuffer->Release() on main thread
+ m_urlLoader->maybeCallOnMainThread(NewRunnableMethod(
+ m_urlLoader.get(), &WebUrlLoaderClient::didReceiveData, m_networkBuffer, bytesRead));
m_networkBuffer = 0;
} else if (m_request && m_request->status().is_io_pending()) {
// got io_pending, so break and wait for read
@@ -408,10 +408,8 @@ void WebRequest::OnReadCompleted(URLRequest* request, int bytesRead)
if (request->status().is_success()) {
m_loadState = GotData;
- m_networkBuffer->AddRef();
- LoaderData* loaderData = new LoaderData(m_urlLoader, m_networkBuffer.get(), bytesRead);
- // m_networkBuffer->Release() on main thread
- m_urlLoader->maybeCallOnMainThread(WebUrlLoaderClient::didReceiveData, loaderData);
+ m_urlLoader->maybeCallOnMainThread(NewRunnableMethod(
+ m_urlLoader.get(), &WebUrlLoaderClient::didReceiveData, m_networkBuffer, bytesRead));
m_networkBuffer = 0;
// Get the rest of the data
diff --git a/WebKit/android/WebCoreSupport/WebRequest.h b/WebKit/android/WebCoreSupport/WebRequest.h
index e52425a..b96126b 100644
--- a/WebKit/android/WebCoreSupport/WebRequest.h
+++ b/WebKit/android/WebCoreSupport/WebRequest.h
@@ -87,9 +87,7 @@ private:
void handleAndroidURL();
void finish(bool success);
- // Not owned
- WebUrlLoaderClient* m_urlLoader;
-
+ scoped_refptr<WebUrlLoaderClient> m_urlLoader;
OwnPtr<URLRequest> m_request;
scoped_refptr<net::IOBuffer> m_networkBuffer;
int m_inputStream;
diff --git a/WebKit/android/WebCoreSupport/WebUrlLoader.h b/WebKit/android/WebCoreSupport/WebUrlLoader.h
index 7106ede..2e76c14 100644
--- a/WebKit/android/WebCoreSupport/WebUrlLoader.h
+++ b/WebKit/android/WebCoreSupport/WebUrlLoader.h
@@ -26,6 +26,7 @@
#ifndef WebUrlLoader_h
#define WebUrlLoader_h
+#include "ChromiumIncludes.h"
#include "ResourceLoaderAndroid.h"
using namespace WebCore;
@@ -47,7 +48,7 @@ private:
WebUrlLoader(WebFrame*, WebCore::ResourceHandle*, const WebCore::ResourceRequest&);
static PassRefPtr<WebUrlLoader> create(WebFrame*, WebCore::ResourceHandle*, const WebCore::ResourceRequest&);
- OwnPtr<WebUrlLoaderClient> m_loaderClient;
+ scoped_refptr<WebUrlLoaderClient> m_loaderClient;
};
} // namespace android
diff --git a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
index 87a76a4..e6c06af 100644
--- a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
+++ b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
@@ -37,12 +37,6 @@
namespace android {
-LoaderData::~LoaderData()
-{
- if (buffer)
- buffer->Release();
-}
-
base::Thread* WebUrlLoaderClient::ioThread()
{
static base::Thread* networkThread = 0;
@@ -77,9 +71,6 @@ ConditionVariable* WebUrlLoaderClient::syncCondition() {
WebUrlLoaderClient::~WebUrlLoaderClient()
{
- base::Thread* thread = ioThread();
- if (thread)
- thread->message_loop()->ReleaseSoon(FROM_HERE, m_request);
}
bool WebUrlLoaderClient::isActive() const
@@ -103,12 +94,10 @@ WebUrlLoaderClient::WebUrlLoaderClient(WebFrame* webFrame, WebCore::ResourceHand
if (webResourceRequest.isAndroidUrl()) {
int inputStream = webFrame->inputStreamForAndroidResource(webResourceRequest.url().c_str(), webResourceRequest.androidFileType());
m_request = new WebRequest(this, webResourceRequest, inputStream);
- m_request->AddRef(); // Matched by ReleaseSoon in destructor
return;
}
m_request = new WebRequest(this, webResourceRequest);
- m_request->AddRef(); // Matched by ReleaseSoon in destructor
// Set uploads before start is called on the request
if (resourceRequest.httpBody() && !(webResourceRequest.method() == "GET" || webResourceRequest.method() == "HEAD")) {
@@ -124,7 +113,7 @@ WebUrlLoaderClient::WebUrlLoaderClient(WebFrame* webFrame, WebCore::ResourceHand
base::Thread* thread = ioThread();
if (thread) {
Vector<char>* data = new Vector<char>(element.m_data);
- thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request, &WebRequest::AppendBytesToUpload, data));
+ thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::AppendBytesToUpload, data));
}
}
break;
@@ -156,16 +145,14 @@ bool WebUrlLoaderClient::start(bool sync, bool isPrivateBrowsing)
m_sync = sync;
if (m_sync) {
AutoLock autoLock(*syncLock());
- thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request, &WebRequest::start, isPrivateBrowsing));
+ thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::start, isPrivateBrowsing));
// Run callbacks until the queue is exhausted and m_finished is true.
while(!m_finished) {
while (!m_queue.empty()) {
- Callback& callback = m_queue.front();
- CallbackFunction* function = callback.a;
- void* context = callback.b;
- (*function)(context);
+ OwnPtr<Task> task(m_queue.front());
m_queue.pop_front();
+ task->Run();
}
if (m_queue.empty() && !m_finished) {
syncCondition()->Wait();
@@ -177,7 +164,7 @@ bool WebUrlLoaderClient::start(bool sync, bool isPrivateBrowsing)
m_resourceHandle = 0;
} else {
// Asynchronous start.
- thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request, &WebRequest::start, isPrivateBrowsing));
+ thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::start, isPrivateBrowsing));
}
return true;
}
@@ -193,7 +180,7 @@ void WebUrlLoaderClient::cancel()
base::Thread* thread = ioThread();
if (thread)
- thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request, &WebRequest::cancel));
+ thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::cancel));
}
void WebUrlLoaderClient::setAuth(const std::string& username, const std::string& password)
@@ -204,7 +191,7 @@ void WebUrlLoaderClient::setAuth(const std::string& username, const std::string&
}
string16 username16 = ASCIIToUTF16(username);
string16 password16 = ASCIIToUTF16(password);
- thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request, &WebRequest::setAuth, username16, password16));
+ thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::setAuth, username16, password16));
}
void WebUrlLoaderClient::cancelAuth()
@@ -213,7 +200,7 @@ void WebUrlLoaderClient::cancelAuth()
if (!thread) {
return;
}
- thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request, &WebRequest::cancelAuth));
+ thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::cancelAuth));
}
void WebUrlLoaderClient::finish()
@@ -224,133 +211,106 @@ void WebUrlLoaderClient::finish()
// We only release the reference here if start() was called asynchronously!
m_resourceHandle = 0;
}
+ m_request = 0;
+}
+
+namespace {
+// Trampoline to wrap a Chromium Task* in a WebKit-style static function + void*.
+static void RunTask(void* v) {
+ OwnPtr<Task> task(static_cast<Task*>(v));
+ task->Run();
+}
}
// This is called from the IO thread, and dispatches the callback to the main thread.
-void WebUrlLoaderClient::maybeCallOnMainThread(CallbackFunction* function, void* context)
+void WebUrlLoaderClient::maybeCallOnMainThread(Task* task)
{
if (m_sync) {
AutoLock autoLock(*syncLock());
if (m_queue.empty()) {
syncCondition()->Broadcast();
}
- m_queue.push_back(Callback(function, context));
+ m_queue.push_back(task);
} else {
// Let WebKit handle it.
- callOnMainThread(function, context);
+ callOnMainThread(RunTask, task);
}
}
// Response methods
-// static - on main thread
-void WebUrlLoaderClient::didReceiveResponse(void* data)
+void WebUrlLoaderClient::didReceiveResponse(PassOwnPtr<WebResponse> webResponse)
{
- OwnPtr<LoaderData> loaderData(static_cast<LoaderData*>(data));
- const WebUrlLoaderClient* loader = loaderData->loader;
- WebResponse webResponse = loaderData->webResponse;
-
- if (!loader->isActive())
+ if (!isActive())
return;
- loader->m_resourceHandle->client()->didReceiveResponse(loader->m_resourceHandle.get(), webResponse.createResourceResponse());
+ m_resourceHandle->client()->didReceiveResponse(m_resourceHandle.get(), webResponse->createResourceResponse());
}
-// static - on main thread
-void WebUrlLoaderClient::didReceiveData(void* data)
+void WebUrlLoaderClient::didReceiveData(scoped_refptr<net::IOBuffer> buf, int size)
{
- OwnPtr<LoaderData> loaderData(static_cast<LoaderData*>(data));
- const WebUrlLoaderClient* loader = loaderData->loader;
- net::IOBuffer* buf = loaderData->buffer;
-
- if (!loader->isActive())
+ if (!isActive())
return;
// didReceiveData will take a copy of the data
- if (loader->m_resourceHandle && loader->m_resourceHandle->client())
- loader->m_resourceHandle->client()->didReceiveData(loader->m_resourceHandle.get(), buf->data(), loaderData->size, loaderData->size);
+ if (m_resourceHandle && m_resourceHandle->client())
+ m_resourceHandle->client()->didReceiveData(m_resourceHandle.get(), buf->data(), size, size);
}
-// static - on main thread
// For data url's
-void WebUrlLoaderClient::didReceiveDataUrl(void* data)
+void WebUrlLoaderClient::didReceiveDataUrl(PassOwnPtr<std::string> str)
{
- OwnPtr<LoaderData> loaderData(static_cast<LoaderData*>(data));
- const WebUrlLoaderClient* loader = loaderData->loader;
-
- if (!loader->isActive())
+ if (!isActive())
return;
- std::string* str = loaderData->string.get();
// didReceiveData will take a copy of the data
- loader->m_resourceHandle->client()->didReceiveData(loader->m_resourceHandle.get(), str->data(), str->size(), str->size());
+ m_resourceHandle->client()->didReceiveData(m_resourceHandle.get(), str->data(), str->size(), str->size());
}
-// static - on main thread
// For special android files
-void WebUrlLoaderClient::didReceiveAndroidFileData(void* data)
+void WebUrlLoaderClient::didReceiveAndroidFileData(PassOwnPtr<std::vector<char> > vector)
{
- OwnPtr<LoaderData> loaderData(static_cast<LoaderData*>(data));
- const WebUrlLoaderClient* loader = loaderData->loader;
-
- if (!loader->isActive())
+ if (!isActive())
return;
// didReceiveData will take a copy of the data
- loader->m_resourceHandle->client()->didReceiveData(loader->m_resourceHandle.get(), &(loaderData->vector->front()), loaderData->size, loaderData->size);
+ m_resourceHandle->client()->didReceiveData(m_resourceHandle.get(), vector->begin(), vector->size(), vector->size());
}
-// static - on main thread
-void WebUrlLoaderClient::didFail(void* data)
+void WebUrlLoaderClient::didFail(PassOwnPtr<WebResponse> webResponse)
{
- OwnPtr<LoaderData> loaderData(static_cast<LoaderData*>(data));
- WebUrlLoaderClient* loader = loaderData->loader;
-
- if (loader->isActive())
- loader->m_resourceHandle->client()->didFail(loader->m_resourceHandle.get(), loaderData->webResponse.createResourceError());
+ if (isActive())
+ m_resourceHandle->client()->didFail(m_resourceHandle.get(), webResponse->createResourceError());
// Always finish a request, if not it will leak
- loader->finish();
+ finish();
}
-// static - on main thread
-void WebUrlLoaderClient::willSendRequest(void* data)
+void WebUrlLoaderClient::willSendRequest(PassOwnPtr<WebResponse> webResponse)
{
- OwnPtr<LoaderData> loaderData(static_cast<LoaderData*>(data));
- const WebUrlLoaderClient* loader = loaderData->loader;
-
- if (!loader->isActive())
+ if (!isActive())
return;
- WebResponse webResponse = loaderData->webResponse;
- OwnPtr<WebCore::ResourceRequest> resourceRequest(new WebCore::ResourceRequest(webResponse.url()));
- loader->m_resourceHandle->client()->willSendRequest(loader->m_resourceHandle.get(), *resourceRequest, webResponse.createResourceResponse());
+ OwnPtr<WebCore::ResourceRequest> resourceRequest(new WebCore::ResourceRequest(webResponse->url()));
+ m_resourceHandle->client()->willSendRequest(m_resourceHandle.get(), *resourceRequest, webResponse->createResourceResponse());
}
-// static - on main thread
-void WebUrlLoaderClient::didFinishLoading(void* data)
+void WebUrlLoaderClient::didFinishLoading()
{
- OwnPtr<LoaderData> loaderData(static_cast<LoaderData*>(data));
- WebUrlLoaderClient* loader = loaderData->loader;
-
- if (loader->isActive())
- loader->m_resourceHandle->client()->didFinishLoading(loader->m_resourceHandle.get(), 0);
+ if (isActive())
+ m_resourceHandle->client()->didFinishLoading(m_resourceHandle.get(), 0);
// Always finish a request, if not it will leak
- loader->finish();
+ finish();
}
-// static - on main thread
-void WebUrlLoaderClient::authRequired(void* data)
+void WebUrlLoaderClient::authRequired(scoped_refptr<net::AuthChallengeInfo> authChallengeInfo)
{
- OwnPtr<LoaderData> loaderData(static_cast<LoaderData*>(data));
- WebUrlLoaderClient* loader = loaderData->loader;
-
- if (!loader->isActive()) {
+ if (!isActive()) {
return;
}
- std::string host = base::SysWideToUTF8(loaderData->authChallengeInfo->host_and_port);
- std::string realm = base::SysWideToUTF8(loaderData->authChallengeInfo->realm);
+ std::string host = base::SysWideToUTF8(authChallengeInfo->host_and_port);
+ std::string realm = base::SysWideToUTF8(authChallengeInfo->realm);
// TODO: Not clear whose responsibility it is to cache credentials. There's nothing
// in AuthChallengeInfo that seems suitable, so for safety we'll tell the UI *not*
@@ -358,7 +318,7 @@ void WebUrlLoaderClient::authRequired(void* data)
// the first call, then "false" for a second call if the credentials are rejected).
bool useCachedCredentials = false;
- loader->m_webFrame->didReceiveAuthenticationChallenge(loader, host, realm, useCachedCredentials);
+ m_webFrame->didReceiveAuthenticationChallenge(this, host, realm, useCachedCredentials);
}
} // namespace android
diff --git a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h
index b568c91..d038489 100644
--- a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h
+++ b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h
@@ -60,10 +60,9 @@ class WebRequest;
// - Implement sync requests
// - Implement downloadFile
// - Implement pauseLoad
-class WebUrlLoaderClient {
+class WebUrlLoaderClient : public base::RefCountedThreadSafe<WebUrlLoaderClient> {
public:
WebUrlLoaderClient(WebFrame*, WebCore::ResourceHandle*, const WebCore::ResourceRequest&);
- ~WebUrlLoaderClient();
// Called from WebCore, will be forwarded to the IO thread
bool start(bool sync, bool isPrivateBrowsing);
@@ -77,22 +76,25 @@ public:
// This is called from the IO thread, and dispatches the callback to the main thread.
// (For asynchronous calls, we just delegate to WebKit's callOnMainThread.)
- void maybeCallOnMainThread(CallbackFunction*, void* context);
+ void maybeCallOnMainThread(Task* task);
// Called by WebRequest (using maybeCallOnMainThread), should be forwarded to WebCore.
- static void didReceiveResponse(void*);
- static void didReceiveData(void*);
- static void didReceiveDataUrl(void*);
- static void didReceiveAndroidFileData(void*);
- static void didFinishLoading(void*);
- static void didFail(void*);
- static void willSendRequest(void*);
- static void authRequired(void*);
+ void didReceiveResponse(PassOwnPtr<WebResponse>);
+ void didReceiveData(scoped_refptr<net::IOBuffer>, int size);
+ void didReceiveDataUrl(PassOwnPtr<std::string>);
+ void didReceiveAndroidFileData(PassOwnPtr<std::vector<char> >);
+ void didFinishLoading();
+ void didFail(PassOwnPtr<WebResponse>);
+ void willSendRequest(PassOwnPtr<WebResponse>);
+ void authRequired(scoped_refptr<net::AuthChallengeInfo>);
// Handle to the chrome IO thread
static base::Thread* ioThread();
private:
+ friend class base::RefCountedThreadSafe<WebUrlLoaderClient>;
+ virtual ~WebUrlLoaderClient();
+
void finish();
WebFrame* m_webFrame;
@@ -101,8 +103,7 @@ private:
bool m_sync;
volatile bool m_finished;
- // Not an OwnPtr since it should be deleted on another thread
- WebRequest* m_request;
+ scoped_refptr<WebRequest> m_request;
// Check if a request is active
bool isActive() const;
@@ -112,44 +113,8 @@ private:
static Lock* syncLock();
static ConditionVariable* syncCondition();
- typedef Tuple2<CallbackFunction*, void*> Callback;
- typedef std::deque<Callback> CallbackQueue;
-
// Queue of callbacks to be executed by the main thread. Must only be accessed inside mutex.
- CallbackQueue m_queue;
-};
-
-// A struct to send more than one thing in a void*, needed for maybeCallOnMainThread
-struct LoaderData {
- net::IOBuffer* buffer;
- WebUrlLoaderClient* loader;
- WebResponse webResponse;
- const int size;
- OwnPtr<std::string*> string;
- OwnPtr<std::vector<char> > vector;
- scoped_refptr<net::AuthChallengeInfo> authChallengeInfo;
-
- LoaderData(WebUrlLoaderClient* l) : buffer(0), loader(l), size(0)
- {
- }
-
- LoaderData(WebUrlLoaderClient* l, std::string* s) : buffer(0), loader(l), size(0), string(s)
- {
- }
-
- LoaderData(WebUrlLoaderClient* l, WebResponse r) : buffer(0), loader(l), webResponse(r), size(0)
- {
- }
-
- LoaderData(WebUrlLoaderClient* l, net::IOBuffer* b, const int s) : buffer(b), loader(l), size(s)
- {
- }
-
- LoaderData(WebUrlLoaderClient* l, std::vector<char>* data, const int s) : buffer(0), loader(l), size(s), vector(data)
- {
- }
-
- ~LoaderData();
+ std::deque<Task*> m_queue;
};
} // namespace android