summaryrefslogtreecommitdiffstats
path: root/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
diff options
context:
space:
mode:
authorIain Merrick <husky@google.com>2010-08-12 16:00:40 +0100
committerIain Merrick <husky@google.com>2010-08-13 18:41:53 +0100
commita01792f8060881461b672472ba3dfdd77044e0a5 (patch)
tree35c7b09d44b07d85d3236984c2d9b3569a40e275 /WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
parentbf0ea53811034ee6502d88349868c53234cc55c2 (diff)
downloadexternal_webkit-a01792f8060881461b672472ba3dfdd77044e0a5.zip
external_webkit-a01792f8060881461b672472ba3dfdd77044e0a5.tar.gz
external_webkit-a01792f8060881461b672472ba3dfdd77044e0a5.tar.bz2
Implement synchronous resource loading in Android.
Change-Id: I31c2c983f0b04db6fb5d2c4ccbe0ea837fc7db2b
Diffstat (limited to 'WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp')
-rw-r--r--WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp76
1 files changed, 66 insertions, 10 deletions
diff --git a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
index bfb8eb7..33f94af 100644
--- a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
+++ b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
@@ -33,6 +33,8 @@
#include "WebRequest.h"
#include "WebResourceRequest.h"
+#include <base/condition_variable.h>
+#include <base/lock.h>
#include <base/thread.h>
#include <net/base/io_buffer.h>
@@ -66,12 +68,21 @@ base::Thread* WebUrlLoaderClient::ioThread()
return networkThread;
}
+Lock* WebUrlLoaderClient::syncLock() {
+ static Lock s_syncLock;
+ return &s_syncLock;
+}
+
+ConditionVariable* WebUrlLoaderClient::syncCondition() {
+ static ConditionVariable s_syncCondition(syncLock());
+ return &s_syncCondition;
+}
+
WebUrlLoaderClient::~WebUrlLoaderClient()
{
base::Thread* thread = ioThread();
if (thread)
thread->message_loop()->ReleaseSoon(FROM_HERE, m_request);
-
}
bool WebUrlLoaderClient::isActive() const
@@ -85,7 +96,10 @@ bool WebUrlLoaderClient::isActive() const
}
WebUrlLoaderClient::WebUrlLoaderClient(WebCore::ResourceHandle* resourceHandle, const WebCore::ResourceRequest& resourceRequest)
- : m_resourceHandle(resourceHandle), m_cancelling(false)
+ : m_resourceHandle(resourceHandle)
+ , m_cancelling(false)
+ , m_sync(false)
+ , m_finished(false)
{
WebResourceRequest webResourceRequest(resourceRequest);
@@ -129,15 +143,40 @@ WebUrlLoaderClient::WebUrlLoaderClient(WebCore::ResourceHandle* resourceHandle,
}
}
-bool WebUrlLoaderClient::start(bool /*sync*/)
+bool WebUrlLoaderClient::start(bool sync)
{
base::Thread* thread = ioThread();
- if (thread) {
- thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request, &WebRequest::start));
- return true;
+ if (!thread) {
+ return false;
}
- return false;
+ m_sync = sync;
+ if (m_sync) {
+ AutoLock autoLock(*syncLock());
+ thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request, &WebRequest::start));
+
+ // 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);
+ m_queue.pop_front();
+ }
+ if (m_queue.empty() && !m_finished) {
+ syncCondition()->Wait();
+ }
+ }
+
+ // This may be the last reference to us, so we may be deleted now.
+ // Don't access any more member variables after releasing this reference.
+ m_resourceHandle = 0;
+ } else {
+ // Asynchronous start.
+ thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request, &WebRequest::start));
+ }
+ return true;
}
void WebUrlLoaderClient::cancel()
@@ -151,9 +190,26 @@ void WebUrlLoaderClient::cancel()
void WebUrlLoaderClient::finish()
{
- // This will probably cause this to be deleted as we are the only one holding a reference to
- // m_resourceHandle, and it is holding the only reference to this.
- m_resourceHandle = 0;
+ m_finished = true;
+ if (!m_sync) {
+ // This is the last reference to us, so we will be deleted now.
+ // We only release the reference here if start() was called asynchronously!
+ m_resourceHandle = 0;
+ }
+}
+
+// This is called from the IO thread, and dispatches the callback to the main thread.
+void WebUrlLoaderClient::maybeCallOnMainThread(CallbackFunction* function, void* context) {
+ if (m_sync) {
+ AutoLock autoLock(*syncLock());
+ if (m_queue.empty()) {
+ syncCondition()->Broadcast();
+ }
+ m_queue.push_back(Callback(function, context));
+ } else {
+ // Let WebKit handle it.
+ callOnMainThread(function, context);
+ }
}
// Response methods