Diff
Modified: trunk/LayoutTests/ChangeLog (113137 => 113138)
--- trunk/LayoutTests/ChangeLog 2012-04-04 04:43:17 UTC (rev 113137)
+++ trunk/LayoutTests/ChangeLog 2012-04-04 05:00:54 UTC (rev 113138)
@@ -1,3 +1,15 @@
+2012-04-03 Yuta Kitamura <[email protected]>
+
+ Crash in WebCore::WorkerThreadableWebSocketChannel::Bridge::mainThreadCreateWebSocketChannel
+ https://bugs.webkit.org/show_bug.cgi?id=82873
+
+ Reviewed by David Levin.
+
+ * http/tests/websocket/tests/hybi/workers/resources/worker-reload-iframe.html: Added.
+ * http/tests/websocket/tests/hybi/workers/resources/worker-reload.js: Added.
+ * http/tests/websocket/tests/hybi/workers/worker-reload-expected.txt: Added.
+ * http/tests/websocket/tests/hybi/workers/worker-reload.html: Added.
+
2012-04-03 Keishi Hattori <[email protected]>
Disable ENABLE_DATALIST for now
Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/workers/resources/worker-reload-iframe.html (0 => 113138)
--- trunk/LayoutTests/http/tests/websocket/tests/hybi/workers/resources/worker-reload-iframe.html (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/workers/resources/worker-reload-iframe.html 2012-04-04 05:00:54 UTC (rev 113138)
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<body>
+<div id="result">Running...</div>
+<script type="text/_javascript_">
+var repeat = 0;
+var regex = new RegExp("#repeat(\\d+)");
+var match = regex.exec(location.hash);
+if (match)
+ repeat = parseInt(match[1]);
+
+if (repeat === 100) {
+ document.getElementById("result").innerHTML = "Done.";
+ parent.document.iframeFinished();
+} else {
+ new Worker("worker-reload.js");
+ location.href = "" + (repeat + 1);
+ setTimeout('location.reload()', 1);
+}
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/workers/resources/worker-reload.js (0 => 113138)
--- trunk/LayoutTests/http/tests/websocket/tests/hybi/workers/resources/worker-reload.js (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/workers/resources/worker-reload.js 2012-04-04 05:00:54 UTC (rev 113138)
@@ -0,0 +1 @@
+new WebSocket('ws://localhost:12345');
Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/workers/worker-reload-expected.txt (0 => 113138)
--- trunk/LayoutTests/http/tests/websocket/tests/hybi/workers/worker-reload-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/workers/worker-reload-expected.txt 2012-04-04 05:00:54 UTC (rev 113138)
@@ -0,0 +1,10 @@
+Reload after WebSocket creation should not cause a crash.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS Inserted <iframe>.
+PASS Test finished.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/workers/worker-reload.html (0 => 113138)
--- trunk/LayoutTests/http/tests/websocket/tests/hybi/workers/worker-reload.html (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/workers/worker-reload.html 2012-04-04 05:00:54 UTC (rev 113138)
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script type="text/_javascript_">
+description("Reload after WebSocket creation should not cause a crash.");
+
+window.jsTestIsAsync = true;
+if (window.layoutTestController)
+ layoutTestController.overridePreference("WebKitHixie76WebSocketProtocolEnabled", 0);
+
+document.iframeFinished = function()
+{
+ testPassed("Test finished.");
+ finishJSTest();
+};
+
+var iframeElement = document.createElement("iframe");
+iframeElement.src = ""
+document.body.appendChild(iframeElement);
+testPassed("Inserted <iframe>.");
+</script>
+<script src=""
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (113137 => 113138)
--- trunk/Source/WebCore/ChangeLog 2012-04-04 04:43:17 UTC (rev 113137)
+++ trunk/Source/WebCore/ChangeLog 2012-04-04 05:00:54 UTC (rev 113138)
@@ -1,3 +1,71 @@
+2012-04-03 Yuta Kitamura <[email protected]>
+
+ Crash in WebCore::WorkerThreadableWebSocketChannel::Bridge::mainThreadCreateWebSocketChannel
+ https://bugs.webkit.org/show_bug.cgi?id=82873
+
+ Reviewed by David Levin.
+
+ WorkerThreadableWebSocketChannel::Bridge should properly handle the cases where inter-thread
+ callback is not called due to the termination of the worker run loop. Specifically, the bridge
+ should not send its "this" pointer to the main thread, because the bridge object may be freed
+ in the worker thread before the main thread starts to process.
+
+ Test: http/tests/websocket/tests/hybi/workers/worker-reload.html
+
+ * Modules/websockets/ThreadableWebSocketChannelClientWrapper.cpp:
+ (WebCore::ThreadableWebSocketChannelClientWrapper::ThreadableWebSocketChannelClientWrapper):
+ (WebCore::ThreadableWebSocketChannelClientWrapper::peer):
+ (WebCore::ThreadableWebSocketChannelClientWrapper::didCreateWebSocketChannel):
+ Renamed from setUseHixie76Protocol, as this funtion now also sets m_peer.
+ Sets m_syncMethodDone to true, because this function is called in the end of
+ synchronous wait of Bridge::initialize().
+ (WebCore::ThreadableWebSocketChannelClientWrapper::clearPeer):
+ (WebCore::ThreadableWebSocketChannelClientWrapper::useHixie76Protocol):
+ * Modules/websockets/ThreadableWebSocketChannelClientWrapper.h:
+ Add WorkerThreadableWebSocketChannel::Peer which is initialized after the creation of
+ WebSocketChannel in the main thread.
+ (ThreadableWebSocketChannelClientWrapper):
+ * Modules/websockets/WorkerThreadableWebSocketChannel.cpp:
+ (WebCore::WorkerThreadableWebSocketChannel::WorkerThreadableWebSocketChannel):
+ Don't do synchronous wait in the constructor, as a member function may be called
+ during the wait before the constructor finishes. The meat of the constructor has
+ moved to initialize() function.
+ (WebCore::WorkerThreadableWebSocketChannel::Bridge::Bridge):
+ (WebCore::WorkerThreadableWebSocketChannel::Bridge::~Bridge):
+ (WorkerContextDidInitializeTask):
+ (WebCore::WorkerContextDidInitializeTask::create):
+ (WebCore::WorkerContextDidInitializeTask::~WorkerContextDidInitializeTask):
+ (WebCore::WorkerContextDidInitializeTask::WorkerContextDidInitializeTask):
+ (WebCore::WorkerThreadableWebSocketChannel::Bridge::mainThreadInitialize):
+ (WebCore::WorkerThreadableWebSocketChannel::Bridge::initialize):
+ Don't pass "this" object to the main thread. Receive the pointer to the peer object
+ via ThreadableWebSocketChannelClientWrapper which is ThreadSafeRefCounted<>.
+ (WebCore::WorkerThreadableWebSocketChannel::Bridge::connect):
+ m_peer may be NULL, and we should not do anything in that case.
+ (WebCore::WorkerThreadableWebSocketChannel::Bridge::send):
+ (WebCore::WorkerThreadableWebSocketChannel::Bridge::bufferedAmount):
+ (WebCore::WorkerThreadableWebSocketChannel::mainThreadClose):
+ (WebCore::WorkerThreadableWebSocketChannel::Bridge::close):
+ (WebCore::WorkerThreadableWebSocketChannel::Bridge::fail):
+ (WebCore::WorkerThreadableWebSocketChannel::Bridge::suspend):
+ (WebCore::WorkerThreadableWebSocketChannel::Bridge::resume):
+ * Modules/websockets/WorkerThreadableWebSocketChannel.h:
+ (WorkerThreadableWebSocketChannel):
+ (WebCore::WorkerThreadableWebSocketChannel::refThreadableWebSocketChannel):
+ (WebCore::WorkerThreadableWebSocketChannel::derefThreadableWebSocketChannel):
+ (Bridge):
+ * workers/DefaultSharedWorkerRepository.cpp:
+ (SharedWorkerProxy):
+ (WebCore::SharedWorkerProxy::postTaskForModeToWorkerContext):
+ * workers/WorkerLoaderProxy.h:
+ (WorkerLoaderProxy::postTaskForModeToWorkerContext):
+ Return bool to indicate whether postTask was successful or not. This is necessary
+ to avoid memory leaks of Peer object in Bridge::initialize() function.
+ * workers/WorkerMessagingProxy.cpp:
+ (WebCore::WorkerMessagingProxy::postTaskForModeToWorkerContext):
+ * workers/WorkerMessagingProxy.h:
+ (WorkerMessagingProxy):
+
2012-04-03 Keishi Hattori <[email protected]>
Disable ENABLE_DATALIST for now
Modified: trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannelClientWrapper.cpp (113137 => 113138)
--- trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannelClientWrapper.cpp 2012-04-04 04:43:17 UTC (rev 113137)
+++ trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannelClientWrapper.cpp 2012-04-04 05:00:54 UTC (rev 113138)
@@ -44,6 +44,7 @@
ThreadableWebSocketChannelClientWrapper::ThreadableWebSocketChannelClientWrapper(ScriptExecutionContext* context, WebSocketChannelClient* client)
: m_context(context)
, m_client(client)
+ , m_peer(0)
, m_syncMethodDone(true)
, m_useHixie76Protocol(true)
, m_sendRequestResult(ThreadableWebSocketChannel::SendFail)
@@ -72,16 +73,28 @@
return m_syncMethodDone;
}
-bool ThreadableWebSocketChannelClientWrapper::useHixie76Protocol() const
+WorkerThreadableWebSocketChannel::Peer* ThreadableWebSocketChannelClientWrapper::peer() const
{
- return m_useHixie76Protocol;
+ return m_peer;
}
-void ThreadableWebSocketChannelClientWrapper::setUseHixie76Protocol(bool useHixie76Protocol)
+void ThreadableWebSocketChannelClientWrapper::didCreateWebSocketChannel(WorkerThreadableWebSocketChannel::Peer* peer, bool useHixie76Protocol)
{
+ m_peer = peer;
m_useHixie76Protocol = useHixie76Protocol;
+ m_syncMethodDone = true;
}
+void ThreadableWebSocketChannelClientWrapper::clearPeer()
+{
+ m_peer = 0;
+}
+
+bool ThreadableWebSocketChannelClientWrapper::useHixie76Protocol() const
+{
+ return m_useHixie76Protocol;
+}
+
String ThreadableWebSocketChannelClientWrapper::subprotocol() const
{
if (m_subprotocol.isEmpty())
Modified: trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannelClientWrapper.h (113137 => 113138)
--- trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannelClientWrapper.h 2012-04-04 04:43:17 UTC (rev 113137)
+++ trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannelClientWrapper.h 2012-04-04 05:00:54 UTC (rev 113138)
@@ -37,6 +37,7 @@
#include "ScriptExecutionContext.h"
#include "ThreadableWebSocketChannel.h"
#include "WebSocketChannelClient.h"
+#include "WorkerThreadableWebSocketChannel.h"
#include <wtf/Forward.h>
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
@@ -56,10 +57,13 @@
void setSyncMethodDone();
bool syncMethodDone() const;
+ WorkerThreadableWebSocketChannel::Peer* peer() const;
+ void didCreateWebSocketChannel(WorkerThreadableWebSocketChannel::Peer*, bool useHixie76Protocol);
+ void clearPeer();
+
// The value of useHixie76Protocol flag is cachable; this value is saved after WebSocketChannel (on the main
// thread) is constructed.
bool useHixie76Protocol() const;
- void setUseHixie76Protocol(bool);
// Subprotocol and extensions are cached too. Will be available when didConnect() callback is invoked.
String subprotocol() const;
@@ -100,6 +104,7 @@
ScriptExecutionContext* m_context;
WebSocketChannelClient* m_client;
+ WorkerThreadableWebSocketChannel::Peer* m_peer;
bool m_syncMethodDone;
bool m_useHixie76Protocol;
// ThreadSafeRefCounted must not have String member variables.
Modified: trunk/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.cpp (113137 => 113138)
--- trunk/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.cpp 2012-04-04 04:43:17 UTC (rev 113137)
+++ trunk/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.cpp 2012-04-04 05:00:54 UTC (rev 113138)
@@ -57,6 +57,7 @@
, m_workerClientWrapper(ThreadableWebSocketChannelClientWrapper::create(context, client))
, m_bridge(Bridge::create(m_workerClientWrapper, m_workerContext, taskMode))
{
+ m_bridge->initialize();
}
WorkerThreadableWebSocketChannel::~WorkerThreadableWebSocketChannel()
@@ -344,49 +345,82 @@
m_loaderProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidClose, m_workerClientWrapper, unhandledBufferedAmount, closingHandshakeCompletion, code, reason), m_taskMode);
}
-void WorkerThreadableWebSocketChannel::Bridge::setWebSocketChannel(ScriptExecutionContext* context, Bridge* thisPtr, Peer* peer, PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, bool useHixie76Protocol)
+WorkerThreadableWebSocketChannel::Bridge::Bridge(PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, PassRefPtr<WorkerContext> workerContext, const String& taskMode)
+ : m_workerClientWrapper(workerClientWrapper)
+ , m_workerContext(workerContext)
+ , m_loaderProxy(m_workerContext->thread()->workerLoaderProxy())
+ , m_taskMode(taskMode)
+ , m_peer(0)
{
- ASSERT_UNUSED(context, context->isWorkerContext());
- thisPtr->m_peer = peer;
- workerClientWrapper->setUseHixie76Protocol(useHixie76Protocol);
- workerClientWrapper->setSyncMethodDone();
+ ASSERT(m_workerClientWrapper.get());
}
-void WorkerThreadableWebSocketChannel::Bridge::mainThreadCreateWebSocketChannel(ScriptExecutionContext* context, Bridge* thisPtr, PassRefPtr<ThreadableWebSocketChannelClientWrapper> prpClientWrapper, const String& taskMode)
+WorkerThreadableWebSocketChannel::Bridge::~Bridge()
{
+ disconnect();
+}
+
+class WorkerContextDidInitializeTask : public ScriptExecutionContext::Task {
+public:
+ static PassOwnPtr<ScriptExecutionContext::Task> create(WorkerThreadableWebSocketChannel::Peer* peer,
+ PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper,
+ bool useHixie76Protocol)
+ {
+ return adoptPtr(new WorkerContextDidInitializeTask(peer, workerClientWrapper, useHixie76Protocol));
+ }
+
+ virtual ~WorkerContextDidInitializeTask() { }
+ virtual void performTask(ScriptExecutionContext* context) OVERRIDE
+ {
+ ASSERT_UNUSED(context, context->isWorkerContext());
+ m_workerClientWrapper->didCreateWebSocketChannel(m_peer, m_useHixie76Protocol);
+ }
+ virtual bool isCleanupTask() const OVERRIDE { return true; }
+
+private:
+ WorkerContextDidInitializeTask(WorkerThreadableWebSocketChannel::Peer* peer,
+ PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper,
+ bool useHixie76Protocol)
+ : m_peer(peer)
+ , m_workerClientWrapper(workerClientWrapper)
+ , m_useHixie76Protocol(useHixie76Protocol)
+ {
+ }
+
+ WorkerThreadableWebSocketChannel::Peer* m_peer;
+ RefPtr<ThreadableWebSocketChannelClientWrapper> m_workerClientWrapper;
+ bool m_useHixie76Protocol;
+};
+
+void WorkerThreadableWebSocketChannel::Bridge::mainThreadInitialize(ScriptExecutionContext* context, WorkerLoaderProxy* loaderProxy, PassRefPtr<ThreadableWebSocketChannelClientWrapper> prpClientWrapper, const String& taskMode)
+{
ASSERT(isMainThread());
ASSERT_UNUSED(context, context->isDocument());
RefPtr<ThreadableWebSocketChannelClientWrapper> clientWrapper = prpClientWrapper;
- Peer* peer = Peer::create(clientWrapper, thisPtr->m_loaderProxy, context, taskMode);
- thisPtr->m_loaderProxy.postTaskForModeToWorkerContext(
- createCallbackTask(&Bridge::setWebSocketChannel,
- AllowCrossThreadAccess(thisPtr),
- AllowCrossThreadAccess(peer), clientWrapper, peer->useHixie76Protocol()), taskMode);
+ Peer* peer = Peer::create(clientWrapper, *loaderProxy, context, taskMode);
+ bool sent = loaderProxy->postTaskForModeToWorkerContext(
+ WorkerContextDidInitializeTask::create(peer, clientWrapper, peer->useHixie76Protocol()), taskMode);
+ if (!sent) {
+ clientWrapper->clearPeer();
+ delete peer;
+ }
}
-WorkerThreadableWebSocketChannel::Bridge::Bridge(PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, PassRefPtr<WorkerContext> workerContext, const String& taskMode)
- : m_workerClientWrapper(workerClientWrapper)
- , m_workerContext(workerContext)
- , m_loaderProxy(m_workerContext->thread()->workerLoaderProxy())
- , m_taskMode(taskMode)
- , m_peer(0)
+void WorkerThreadableWebSocketChannel::Bridge::initialize()
{
- ASSERT(m_workerClientWrapper.get());
+ ASSERT(!m_peer);
setMethodNotCompleted();
+ RefPtr<Bridge> protect(this);
m_loaderProxy.postTaskToLoader(
- createCallbackTask(&Bridge::mainThreadCreateWebSocketChannel,
- AllowCrossThreadAccess(this), m_workerClientWrapper, m_taskMode));
+ createCallbackTask(&Bridge::mainThreadInitialize,
+ AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper, m_taskMode));
waitForMethodCompletion();
- ASSERT(m_peer);
+ // m_peer may be null when the nested runloop exited before a peer has created.
+ m_peer = m_workerClientWrapper->peer();
}
-WorkerThreadableWebSocketChannel::Bridge::~Bridge()
-{
- disconnect();
-}
-
void WorkerThreadableWebSocketChannel::mainThreadConnect(ScriptExecutionContext* context, Peer* peer, const KURL& url, const String& protocol)
{
ASSERT(isMainThread());
@@ -399,7 +433,8 @@
void WorkerThreadableWebSocketChannel::Bridge::connect(const KURL& url, const String& protocol)
{
ASSERT(m_workerClientWrapper);
- ASSERT(m_peer);
+ if (!m_peer)
+ return;
m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadConnect, AllowCrossThreadAccess(m_peer), url, protocol));
}
@@ -434,9 +469,8 @@
ThreadableWebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(const String& message)
{
- if (!m_workerClientWrapper)
+ if (!m_workerClientWrapper || !m_peer)
return ThreadableWebSocketChannel::SendFail;
- ASSERT(m_peer);
setMethodNotCompleted();
m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadSend, AllowCrossThreadAccess(m_peer), message));
RefPtr<Bridge> protect(this);
@@ -449,9 +483,8 @@
ThreadableWebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(const ArrayBuffer& binaryData)
{
- if (!m_workerClientWrapper)
+ if (!m_workerClientWrapper || !m_peer)
return ThreadableWebSocketChannel::SendFail;
- ASSERT(m_peer);
// ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied into Vector<char>.
OwnPtr<Vector<char> > data = "" Vector<char>(binaryData.byteLength()));
if (binaryData.byteLength())
@@ -468,9 +501,8 @@
ThreadableWebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(const Blob& binaryData)
{
- if (!m_workerClientWrapper)
+ if (!m_workerClientWrapper || !m_peer)
return ThreadableWebSocketChannel::SendFail;
- ASSERT(m_peer);
setMethodNotCompleted();
m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadSendBlob, AllowCrossThreadAccess(m_peer), binaryData.url(), binaryData.type(), binaryData.size()));
RefPtr<Bridge> protect(this);
@@ -492,9 +524,8 @@
unsigned long WorkerThreadableWebSocketChannel::Bridge::bufferedAmount()
{
- if (!m_workerClientWrapper)
+ if (!m_workerClientWrapper || !m_peer)
return 0;
- ASSERT(m_peer);
setMethodNotCompleted();
m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadBufferedAmount, AllowCrossThreadAccess(m_peer)));
RefPtr<Bridge> protect(this);
@@ -505,7 +536,7 @@
return 0;
}
-void WorkerThreadableWebSocketChannel::mainThreadClose(ScriptExecutionContext* context, Peer* peer, int code, const String&reason)
+void WorkerThreadableWebSocketChannel::mainThreadClose(ScriptExecutionContext* context, Peer* peer, int code, const String& reason)
{
ASSERT(isMainThread());
ASSERT_UNUSED(context, context->isDocument());
@@ -516,7 +547,8 @@
void WorkerThreadableWebSocketChannel::Bridge::close(int code, const String& reason)
{
- ASSERT(m_peer);
+ if (!m_peer)
+ return;
m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadClose, AllowCrossThreadAccess(m_peer), code, reason));
}
@@ -531,7 +563,8 @@
void WorkerThreadableWebSocketChannel::Bridge::fail(const String& reason)
{
- ASSERT(m_peer);
+ if (!m_peer)
+ return;
m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadFail, AllowCrossThreadAccess(m_peer), reason));
}
@@ -566,7 +599,8 @@
void WorkerThreadableWebSocketChannel::Bridge::suspend()
{
- ASSERT(m_peer);
+ if (!m_peer)
+ return;
m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadSuspend, AllowCrossThreadAccess(m_peer)));
}
@@ -581,7 +615,8 @@
void WorkerThreadableWebSocketChannel::Bridge::resume()
{
- ASSERT(m_peer);
+ if (!m_peer)
+ return;
m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadResume, AllowCrossThreadAccess(m_peer)));
}
Modified: trunk/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.h (113137 => 113138)
--- trunk/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.h 2012-04-04 04:43:17 UTC (rev 113137)
+++ trunk/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.h 2012-04-04 05:00:54 UTC (rev 113138)
@@ -36,6 +36,7 @@
#include "PlatformString.h"
#include "ThreadableWebSocketChannel.h"
#include "WebSocketChannelClient.h"
+#include "WorkerContext.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -75,14 +76,6 @@
virtual void suspend() OVERRIDE;
virtual void resume() OVERRIDE;
- using RefCounted<WorkerThreadableWebSocketChannel>::ref;
- using RefCounted<WorkerThreadableWebSocketChannel>::deref;
-
-protected:
- virtual void refThreadableWebSocketChannel() { ref(); }
- virtual void derefThreadableWebSocketChannel() { deref(); }
-
-private:
// Generated by the bridge. The Peer and its bridge should have identical
// lifetimes.
class Peer : public WebSocketChannelClient {
@@ -123,6 +116,14 @@
String m_taskMode;
};
+ using RefCounted<WorkerThreadableWebSocketChannel>::ref;
+ using RefCounted<WorkerThreadableWebSocketChannel>::deref;
+
+protected:
+ virtual void refThreadableWebSocketChannel() { ref(); }
+ virtual void derefThreadableWebSocketChannel() { deref(); }
+
+private:
// Bridge for Peer. Running on the worker thread.
class Bridge : public RefCounted<Bridge> {
public:
@@ -131,6 +132,7 @@
return adoptRef(new Bridge(workerClientWrapper, workerContext, taskMode));
}
~Bridge();
+ void initialize();
void connect(const KURL&, const String& protocol);
ThreadableWebSocketChannel::SendResult send(const String& message);
ThreadableWebSocketChannel::SendResult send(const ArrayBuffer&);
@@ -151,7 +153,7 @@
static void setWebSocketChannel(ScriptExecutionContext*, Bridge* thisPtr, Peer*, PassRefPtr<ThreadableWebSocketChannelClientWrapper>, bool useHixie76Protocol);
// Executed on the main thread to create a Peer for this bridge.
- static void mainThreadCreateWebSocketChannel(ScriptExecutionContext*, Bridge* thisPtr, PassRefPtr<ThreadableWebSocketChannelClientWrapper>, const String& taskMode);
+ static void mainThreadInitialize(ScriptExecutionContext*, WorkerLoaderProxy*, PassRefPtr<ThreadableWebSocketChannelClientWrapper>, const String& taskMode);
// Executed on the worker context's thread.
void clearClientWrapper();
Modified: trunk/Source/WebCore/workers/DefaultSharedWorkerRepository.cpp (113137 => 113138)
--- trunk/Source/WebCore/workers/DefaultSharedWorkerRepository.cpp 2012-04-04 04:43:17 UTC (rev 113137)
+++ trunk/Source/WebCore/workers/DefaultSharedWorkerRepository.cpp 2012-04-04 05:00:54 UTC (rev 113138)
@@ -77,7 +77,7 @@
// WorkerLoaderProxy
virtual void postTaskToLoader(PassOwnPtr<ScriptExecutionContext::Task>);
- virtual void postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task>, const String&);
+ virtual bool postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task>, const String&);
// WorkerReportingProxy
virtual void postExceptionToWorkerObject(const String& errorMessage, int lineNumber, const String& sourceURL);
@@ -151,12 +151,13 @@
document->postTask(task);
}
-void SharedWorkerProxy::postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode)
+bool SharedWorkerProxy::postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode)
{
if (isClosing())
- return;
+ return false;
ASSERT(m_thread);
m_thread->runLoop().postTaskForMode(task, mode);
+ return true;
}
static void postExceptionTask(ScriptExecutionContext* context, const String& errorMessage, int lineNumber, const String& sourceURL)
Modified: trunk/Source/WebCore/workers/WorkerLoaderProxy.h (113137 => 113138)
--- trunk/Source/WebCore/workers/WorkerLoaderProxy.h 2012-04-04 04:43:17 UTC (rev 113137)
+++ trunk/Source/WebCore/workers/WorkerLoaderProxy.h 2012-04-04 05:00:54 UTC (rev 113138)
@@ -53,7 +53,8 @@
// Posts callbacks from loading code to the WorkerContext. The 'mode' is used to differentiate
// specific synchronous loading requests so they can be 'nested', per spec.
- virtual void postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task>, const String& mode) = 0;
+ // Returns true if the task was posted successfully.
+ virtual bool postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task>, const String& mode) = 0;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/workers/WorkerMessagingProxy.cpp (113137 => 113138)
--- trunk/Source/WebCore/workers/WorkerMessagingProxy.cpp 2012-04-04 04:43:17 UTC (rev 113137)
+++ trunk/Source/WebCore/workers/WorkerMessagingProxy.cpp 2012-04-04 05:00:54 UTC (rev 113138)
@@ -296,13 +296,14 @@
m_queuedEarlyTasks.append(MessageWorkerContextTask::create(message, channels));
}
-void WorkerMessagingProxy::postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode)
+bool WorkerMessagingProxy::postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode)
{
if (m_askedToTerminate)
- return;
+ return false;
ASSERT(m_workerThread);
m_workerThread->runLoop().postTaskForMode(task, mode);
+ return true;
}
void WorkerMessagingProxy::postTaskToLoader(PassOwnPtr<ScriptExecutionContext::Task> task)
Modified: trunk/Source/WebCore/workers/WorkerMessagingProxy.h (113137 => 113138)
--- trunk/Source/WebCore/workers/WorkerMessagingProxy.h 2012-04-04 04:43:17 UTC (rev 113137)
+++ trunk/Source/WebCore/workers/WorkerMessagingProxy.h 2012-04-04 05:00:54 UTC (rev 113138)
@@ -82,7 +82,7 @@
// These methods are called on different threads to schedule loading
// requests and to send callbacks back to WorkerContext.
virtual void postTaskToLoader(PassOwnPtr<ScriptExecutionContext::Task>);
- virtual void postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task>, const String& mode);
+ virtual bool postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task>, const String& mode);
void workerThreadCreated(PassRefPtr<DedicatedWorkerThread>);
Modified: trunk/Source/WebKit/chromium/ChangeLog (113137 => 113138)
--- trunk/Source/WebKit/chromium/ChangeLog 2012-04-04 04:43:17 UTC (rev 113137)
+++ trunk/Source/WebKit/chromium/ChangeLog 2012-04-04 05:00:54 UTC (rev 113138)
@@ -1,3 +1,21 @@
+2012-04-03 Yuta Kitamura <[email protected]>
+
+ Crash in WebCore::WorkerThreadableWebSocketChannel::Bridge::mainThreadCreateWebSocketChannel
+ https://bugs.webkit.org/show_bug.cgi?id=82873
+
+ Reviewed by David Levin.
+
+ Change the function signature of WorkerLoaderProxy::postTaskForModeToWorkerContext().
+
+ * src/WebSharedWorkerImpl.cpp:
+ (WebKit::WebSharedWorkerImpl::postTaskForModeToWorkerContext):
+ * src/WebSharedWorkerImpl.h:
+ (WebSharedWorkerImpl):
+ * src/WebWorkerClientImpl.cpp:
+ (WebKit::WebWorkerClientImpl::postTaskForModeToWorkerContext):
+ * src/WebWorkerClientImpl.h:
+ (WebWorkerClientImpl):
+
2012-04-03 Ian Vollick <[email protected]>
[chromium] Include Image.h in TextFieldDecoratorImpl.cpp
Modified: trunk/Source/WebKit/chromium/src/WebSharedWorkerImpl.cpp (113137 => 113138)
--- trunk/Source/WebKit/chromium/src/WebSharedWorkerImpl.cpp 2012-04-04 04:43:17 UTC (rev 113137)
+++ trunk/Source/WebKit/chromium/src/WebSharedWorkerImpl.cpp 2012-04-04 05:00:54 UTC (rev 113138)
@@ -320,10 +320,11 @@
m_loadingDocument->postTask(task);
}
-void WebSharedWorkerImpl::postTaskForModeToWorkerContext(
+bool WebSharedWorkerImpl::postTaskForModeToWorkerContext(
PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode)
{
m_workerThread->runLoop().postTaskForMode(task, mode);
+ return true;
}
Modified: trunk/Source/WebKit/chromium/src/WebSharedWorkerImpl.h (113137 => 113138)
--- trunk/Source/WebKit/chromium/src/WebSharedWorkerImpl.h 2012-04-04 04:43:17 UTC (rev 113137)
+++ trunk/Source/WebKit/chromium/src/WebSharedWorkerImpl.h 2012-04-04 05:00:54 UTC (rev 113138)
@@ -86,7 +86,7 @@
// WebCore::WorkerLoaderProxy methods:
virtual void postTaskToLoader(PassOwnPtr<WebCore::ScriptExecutionContext::Task>);
- virtual void postTaskForModeToWorkerContext(
+ virtual bool postTaskForModeToWorkerContext(
PassOwnPtr<WebCore::ScriptExecutionContext::Task>, const WTF::String& mode);
// WebFrameClient methods to support resource loading thru the 'shadow page'.
Modified: trunk/Source/WebKit/chromium/src/WebWorkerClientImpl.cpp (113137 => 113138)
--- trunk/Source/WebKit/chromium/src/WebWorkerClientImpl.cpp 2012-04-04 04:43:17 UTC (rev 113137)
+++ trunk/Source/WebKit/chromium/src/WebWorkerClientImpl.cpp 2012-04-04 05:00:54 UTC (rev 113138)
@@ -149,9 +149,10 @@
m_proxy->postTaskToLoader(task);
}
-void WebWorkerClientImpl::postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode)
+bool WebWorkerClientImpl::postTaskForModeToWorkerContext(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode)
{
m_proxy->postTaskForModeToWorkerContext(task, mode);
+ return true;
}
void WebWorkerClientImpl::postMessageToWorkerObject(PassRefPtr<SerializedScriptValue> value, PassOwnPtr<MessagePortChannelArray> ports)
Modified: trunk/Source/WebKit/chromium/src/WebWorkerClientImpl.h (113137 => 113138)
--- trunk/Source/WebKit/chromium/src/WebWorkerClientImpl.h 2012-04-04 04:43:17 UTC (rev 113137)
+++ trunk/Source/WebKit/chromium/src/WebWorkerClientImpl.h 2012-04-04 05:00:54 UTC (rev 113138)
@@ -86,7 +86,7 @@
#endif
// WebCore::WorkerLoaderProxy methods:
virtual void postTaskToLoader(PassOwnPtr<WebCore::ScriptExecutionContext::Task>) OVERRIDE;
- virtual void postTaskForModeToWorkerContext(PassOwnPtr<WebCore::ScriptExecutionContext::Task>, const String& mode) OVERRIDE;
+ virtual bool postTaskForModeToWorkerContext(PassOwnPtr<WebCore::ScriptExecutionContext::Task>, const String& mode) OVERRIDE;
// WebCore::WorkerObjectProxy methods:
virtual void postMessageToWorkerObject(PassRefPtr<WebCore::SerializedScriptValue>, PassOwnPtr<WebCore::MessagePortChannelArray>) OVERRIDE;