[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.18-1-697-g2f78b87
ukai at chromium.org
ukai at chromium.org
Wed Jan 20 22:14:54 UTC 2010
The following commit has been merged in the debian/unstable branch:
commit 42361617dba31095a08ea056a038e230f48e935c
Author: ukai at chromium.org <ukai at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Thu Jan 7 02:33:35 2010 +0000
2010-01-06 Fumitoshi Ukai <ukai at chromium.org>
Reviewed by David Levin
Add WebSocket feature in Worker
https://bugs.webkit.org/show_bug.cgi?id=32214
* websocket/tests/workers/resources/simple_wsh.py: Copied from LayoutTests/websocket/tests/simple_wsh.py.
* websocket/tests/workers/resources/worker-simple.js: Added.
* websocket/tests/workers/worker-simple-expected.txt: Added.
* websocket/tests/workers/worker-simple.html: Added.
2010-01-06 Fumitoshi Ukai <ukai at chromium.org>
Reviewed by David Levin.
Add WebSocket feature in Worker
https://bugs.webkit.org/show_bug.cgi?id=32214
Introduce ThreadableWebSocketChannel interface and add
WorkerThreadableWebSocketChannel for Worker.
WorkerThreadableWebSocketChannel uses WebSocketChannel in the
main thread, which is managed by Peer and communicated via Bridge.
Test: websocket/tests/workers/worker-simple.html
* GNUmakefile.am:
* WebCore.gypi:
* WebCore.pro:
* WebCore.vcproj/WebCore.vcproj:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSWebSocketConstructor.h:
* bindings/js/JSWorkerContextCustom.cpp:
(WebCore::JSWorkerContext::webSocket):
* bindings/v8/WorkerContextExecutionProxy.cpp:
(WebCore::WorkerContextExecutionProxy::convertEventTargetToV8Object):
* bindings/v8/custom/V8WebSocketCustom.cpp:
(WebCore::V8Custom::v8WebSocketConstructorCallback):
* bindings/v8/custom/V8WorkerContextCustom.cpp:
* platform/CrossThreadCopier.cpp:
(WebCore::::copy):
* platform/CrossThreadCopier.h:
(WebCore::):
* websockets/ThreadableWebSocketChannel.cpp: Added.
* websockets/ThreadableWebSocketChannel.h: Added.
* websockets/ThreadableWebSocketChannelClientWrapper.h: Added.
* websockets/WebSocket.cpp:
(WebCore::WebSocket::connect):
(WebCore::WebSocket::didReceiveMessage):
* websockets/WebSocket.h:
* websockets/WebSocketChannel.h:
(WebCore::WebSocketChannel::refThreadableWebSocketChannel):
(WebCore::WebSocketChannel::derefThreadableWebSocketChannel):
* websockets/WebSocketChannelClient.h:
* websockets/WebSocketHandshake.h:
* websockets/WorkerThreadableWebSocketChannel.cpp: Added.
* websockets/WorkerThreadableWebSocketChannel.h: Added.
* workers/WorkerContext.idl:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@52892 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index eb78230..ddfcb81 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,15 @@
+2010-01-06 Fumitoshi Ukai <ukai at chromium.org>
+
+ Reviewed by David Levin
+
+ Add WebSocket feature in Worker
+ https://bugs.webkit.org/show_bug.cgi?id=32214
+
+ * websocket/tests/workers/resources/simple_wsh.py: Copied from LayoutTests/websocket/tests/simple_wsh.py.
+ * websocket/tests/workers/resources/worker-simple.js: Added.
+ * websocket/tests/workers/worker-simple-expected.txt: Added.
+ * websocket/tests/workers/worker-simple.html: Added.
+
2010-01-06 Adam Bergkvist <adam.bergkvist at ericsson.com>
Reviewed by Darin Adler.
diff --git a/LayoutTests/websocket/tests/simple_wsh.py b/LayoutTests/websocket/tests/workers/resources/simple_wsh.py
similarity index 100%
copy from LayoutTests/websocket/tests/simple_wsh.py
copy to LayoutTests/websocket/tests/workers/resources/simple_wsh.py
diff --git a/LayoutTests/websocket/tests/workers/resources/worker-simple.js b/LayoutTests/websocket/tests/workers/resources/worker-simple.js
new file mode 100644
index 0000000..9825b48
--- /dev/null
+++ b/LayoutTests/websocket/tests/workers/resources/worker-simple.js
@@ -0,0 +1,37 @@
+if (self.postMessage)
+ runTests();
+else
+ onconnect = handleConnect();
+
+function handleConnect(evevnt)
+{
+ // For shared workers, create a faux postMessage() API to send message back to the parent page.
+ self.postMessage = function (message) { event.ports[0].postMessage(message); };
+ runTests();
+};
+
+function runTests()
+{
+ try {
+ postMessage("PASS: worker: init");
+ if ('WebSocket' in self)
+ postMessage("PASS: worker: WebSocket exists");
+ else
+ postMessage("PASS: worker: no WebSocket");
+ ws = new WebSocket('ws://localhost:8880/websocket/tests/workers/resources/simple');
+ ws.onopen = function() {
+ postMessage("PASS: worker: Connected.");
+ };
+ ws.onmessage = function(evt) {
+ postMessage("PASS: worker: Received: '" + evt.data + "'");
+ };
+ ws.onclose = function() {
+ postMessage("PASS: worker: Closed.");
+ postMessage("DONE");
+ };
+ } catch (e) {
+ postMessage("FAIL: worker: Unexpected exception: " + e);
+ } finally {
+ postMessage("PASS: worker: successfullyParsed:" + ws);
+ }
+};
diff --git a/LayoutTests/websocket/tests/workers/worker-simple-expected.txt b/LayoutTests/websocket/tests/workers/worker-simple-expected.txt
new file mode 100644
index 0000000..165a842
--- /dev/null
+++ b/LayoutTests/websocket/tests/workers/worker-simple-expected.txt
@@ -0,0 +1,13 @@
+Test for Web Socket in Worker.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS: worker: init
+PASS: worker: WebSocket exists
+PASS: worker: successfullyParsed:[object WebSocket]
+PASS: worker: Connected.
+PASS: worker: Received: 'Hello from Simple WSH.'
+PASS: worker: Closed.
+DONE
+TEST COMPLETE
+
diff --git a/LayoutTests/websocket/tests/workers/worker-simple.html b/LayoutTests/websocket/tests/workers/worker-simple.html
new file mode 100644
index 0000000..bc24e72
--- /dev/null
+++ b/LayoutTests/websocket/tests/workers/worker-simple.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head></head>
+<body>
+<p>Test for Web Socket in Worker.</p>
+<p></p>
+<p>On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".</p>
+<pre id=log>
+</pre>
+<script>
+if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+}
+
+function log(message)
+{
+ document.getElementById("log").innerHTML += message + "\n";
+}
+
+function endTest()
+{
+ log("TEST COMPLETE");
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+var worker = new Worker('resources/worker-simple.js');
+worker.onmessage = function (evt) {
+ log(evt.data);
+ if (evt.data == "DONE")
+ endTest();
+};
+</script>
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 68b3fdc..f8f4c35 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,50 @@
+2010-01-06 Fumitoshi Ukai <ukai at chromium.org>
+
+ Reviewed by David Levin.
+
+ Add WebSocket feature in Worker
+ https://bugs.webkit.org/show_bug.cgi?id=32214
+
+ Introduce ThreadableWebSocketChannel interface and add
+ WorkerThreadableWebSocketChannel for Worker.
+ WorkerThreadableWebSocketChannel uses WebSocketChannel in the
+ main thread, which is managed by Peer and communicated via Bridge.
+
+ Test: websocket/tests/workers/worker-simple.html
+
+ * GNUmakefile.am:
+ * WebCore.gypi:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * bindings/js/JSWebSocketConstructor.h:
+ * bindings/js/JSWorkerContextCustom.cpp:
+ (WebCore::JSWorkerContext::webSocket):
+ * bindings/v8/WorkerContextExecutionProxy.cpp:
+ (WebCore::WorkerContextExecutionProxy::convertEventTargetToV8Object):
+ * bindings/v8/custom/V8WebSocketCustom.cpp:
+ (WebCore::V8Custom::v8WebSocketConstructorCallback):
+ * bindings/v8/custom/V8WorkerContextCustom.cpp:
+ * platform/CrossThreadCopier.cpp:
+ (WebCore::::copy):
+ * platform/CrossThreadCopier.h:
+ (WebCore::):
+ * websockets/ThreadableWebSocketChannel.cpp: Added.
+ * websockets/ThreadableWebSocketChannel.h: Added.
+ * websockets/ThreadableWebSocketChannelClientWrapper.h: Added.
+ * websockets/WebSocket.cpp:
+ (WebCore::WebSocket::connect):
+ (WebCore::WebSocket::didReceiveMessage):
+ * websockets/WebSocket.h:
+ * websockets/WebSocketChannel.h:
+ (WebCore::WebSocketChannel::refThreadableWebSocketChannel):
+ (WebCore::WebSocketChannel::derefThreadableWebSocketChannel):
+ * websockets/WebSocketChannelClient.h:
+ * websockets/WebSocketHandshake.h:
+ * websockets/WorkerThreadableWebSocketChannel.cpp: Added.
+ * websockets/WorkerThreadableWebSocketChannel.h: Added.
+ * workers/WorkerContext.idl:
+
2010-01-06 Adam Bergkvist <adam.bergkvist at ericsson.com>
Reviewed by Darin Adler.
diff --git a/WebCore/GNUmakefile.am b/WebCore/GNUmakefile.am
index c142afb..67b671c 100644
--- a/WebCore/GNUmakefile.am
+++ b/WebCore/GNUmakefile.am
@@ -3386,6 +3386,15 @@ webcore_sources += \
WebCore/websockets/WebSocketHandshake.cpp \
WebCore/websockets/WebSocketHandshake.h
+if ENABLE_WORKERS
+webcore_sources += \
+ WebCore/websockets/ThreadableWebSocketChannel.cpp \
+ WebCore/websockets/ThreadableWebSocketChannel.h \
+ WebCore/websockets/ThreadableWebSocketChannelClientWrapper.h \
+ WebCore/websockets/WorkerThreadableWebSocketChannel.cpp \
+ WebCore/websockets/WorkerThreadableWebSocketChannel.h
+endif
+
webcoregtk_sources += \
WebCore/platform/network/soup/SocketStreamError.h \
WebCore/platform/network/soup/SocketStreamHandle.h \
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index 339b6fb..ec1092e 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -3556,6 +3556,9 @@
'svg/SynchronizablePropertyController.cpp',
'svg/SynchronizablePropertyController.h',
'svg/SynchronizableTypeWrapper.h',
+ 'websockets/ThreadableWebSocketChannel.cpp',
+ 'websockets/ThreadableWebSocketChannel.h',
+ 'websockets/ThreadableWebSocketChannelClientWrapper.h',
'websockets/WebSocket.cpp',
'websockets/WebSocket.h',
'websockets/WebSocketChannel.cpp',
@@ -3563,6 +3566,8 @@
'websockets/WebSocketChannelClient.h',
'websockets/WebSocketHandshake.cpp',
'websockets/WebSocketHandshake.h',
+ 'websockets/WorkerThreadableWebSocketChannel.cpp',
+ 'websockets/WorkerThreadableWebSocketChannel.h',
'workers/AbstractWorker.cpp',
'workers/AbstractWorker.h',
'workers/DedicatedWorkerContext.cpp',
diff --git a/WebCore/WebCore.pro b/WebCore/WebCore.pro
index 422e3ef..4d3e9e6 100644
--- a/WebCore/WebCore.pro
+++ b/WebCore/WebCore.pro
@@ -3222,6 +3222,12 @@ SOURCES += \
platform/network/qt/SocketStreamHandleSoup.cpp \
bindings/js/JSWebSocketCustom.cpp \
bindings/js/JSWebSocketConstructor.cpp
+
+contains(DEFINES, ENABLE_WORKERS=1) {
+SOURCES += \
+ websockets/ThreadableWebSocketChannel.cpp \
+ websockets/WorkerThreadableWebSocketChannel.cpp
+}
}
# GENERATOR 1: IDL compiler
diff --git a/WebCore/WebCore.vcproj/WebCore.vcproj b/WebCore/WebCore.vcproj/WebCore.vcproj
index f0eac43..9e30a53 100644
--- a/WebCore/WebCore.vcproj/WebCore.vcproj
+++ b/WebCore/WebCore.vcproj/WebCore.vcproj
@@ -43377,6 +43377,18 @@
Name="websockets"
>
<File
+ RelativePath="..\websockets\ThreadableWebSocketChannel.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\websockets\ThreadableWebSocketChannel.h"
+ >
+ </File>
+ <File
+ RelativePath="..\websockets\ThreadableWebSocketChannelClientWrapper.h"
+ >
+ </File>
+ <File
RelativePath="..\websockets\WebSocket.cpp"
>
</File>
@@ -43404,6 +43416,14 @@
RelativePath="..\websockets\WebSocketHandshake.h"
>
</File>
+ <File
+ RelativePath="..\websockets\WorkerThreadableWebSocketChannel.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\websockets\WorkerThreadableWebSocketChannel.h"
+ >
+ </File>
</Filter>
<File
RelativePath="..\config.h"
diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj
index 6918033..2770b1e 100644
--- a/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -968,6 +968,11 @@
510D4A4E103177A20049EA54 /* WebSocketChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 510D4A47103177A20049EA54 /* WebSocketChannel.cpp */; };
510D4A4F103177A20049EA54 /* WebSocketChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 510D4A48103177A20049EA54 /* WebSocketChannel.h */; };
510D4A50103177A20049EA54 /* WebSocketChannelClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 510D4A49103177A20049EA54 /* WebSocketChannelClient.h */; };
+ 5112247210CFB8C6008099D7 /* ThreadableWebSocketChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5112247110CFB8C6008099D7 /* ThreadableWebSocketChannel.cpp */; };
+ 5112247410CFB8D8008099D7 /* ThreadableWebSocketChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 5112247310CFB8D8008099D7 /* ThreadableWebSocketChannel.h */; };
+ 5112247610CFB8E8008099D7 /* ThreadableWebSocketChannelClientWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 5112247510CFB8E8008099D7 /* ThreadableWebSocketChannelClientWrapper.h */; };
+ 5112247810CFB8F4008099D7 /* WorkerThreadableWebSocketChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5112247710CFB8F4008099D7 /* WorkerThreadableWebSocketChannel.cpp */; };
+ 5112247A10CFB8FF008099D7 /* WorkerThreadableWebSocketChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 5112247910CFB8FF008099D7 /* WorkerThreadableWebSocketChannel.h */; };
5116D9770CF177BD00C2B84D /* DatabaseDetails.h in Headers */ = {isa = PBXBuildFile; fileRef = 5116D9750CF177BD00C2B84D /* DatabaseDetails.h */; settings = {ATTRIBUTES = (Private, ); }; };
511F23170DC160DA004F0032 /* LocalStorageTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 511F23130DC160DA004F0032 /* LocalStorageTask.cpp */; };
511F23180DC160DA004F0032 /* LocalStorageTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 511F23140DC160DA004F0032 /* LocalStorageTask.h */; };
@@ -6287,6 +6292,11 @@
510D4A47103177A20049EA54 /* WebSocketChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSocketChannel.cpp; sourceTree = "<group>"; };
510D4A48103177A20049EA54 /* WebSocketChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSocketChannel.h; sourceTree = "<group>"; };
510D4A49103177A20049EA54 /* WebSocketChannelClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSocketChannelClient.h; sourceTree = "<group>"; };
+ 5112247110CFB8C6008099D7 /* ThreadableWebSocketChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadableWebSocketChannel.cpp; sourceTree = "<group>"; };
+ 5112247310CFB8D8008099D7 /* ThreadableWebSocketChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadableWebSocketChannel.h; sourceTree = "<group>"; };
+ 5112247510CFB8E8008099D7 /* ThreadableWebSocketChannelClientWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadableWebSocketChannelClientWrapper.h; sourceTree = "<group>"; };
+ 5112247710CFB8F4008099D7 /* WorkerThreadableWebSocketChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerThreadableWebSocketChannel.cpp; sourceTree = "<group>"; };
+ 5112247910CFB8FF008099D7 /* WorkerThreadableWebSocketChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerThreadableWebSocketChannel.h; sourceTree = "<group>"; };
5116D9750CF177BD00C2B84D /* DatabaseDetails.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DatabaseDetails.h; sourceTree = "<group>"; };
511F23130DC160DA004F0032 /* LocalStorageTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LocalStorageTask.cpp; sourceTree = "<group>"; };
511F23140DC160DA004F0032 /* LocalStorageTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocalStorageTask.h; sourceTree = "<group>"; };
@@ -11000,6 +11010,11 @@
518A34BD1026C831001B6896 /* websockets */ = {
isa = PBXGroup;
children = (
+ 5112247910CFB8FF008099D7 /* WorkerThreadableWebSocketChannel.h */,
+ 5112247710CFB8F4008099D7 /* WorkerThreadableWebSocketChannel.cpp */,
+ 5112247510CFB8E8008099D7 /* ThreadableWebSocketChannelClientWrapper.h */,
+ 5112247310CFB8D8008099D7 /* ThreadableWebSocketChannel.h */,
+ 5112247110CFB8C6008099D7 /* ThreadableWebSocketChannel.cpp */,
518A34BE1026C831001B6896 /* WebSocket.cpp */,
518A34BF1026C831001B6896 /* WebSocket.h */,
518A34C01026C831001B6896 /* WebSocket.idl */,
@@ -18291,6 +18306,9 @@
08735FB910E91232006D6FAD /* SVGMarkerLayoutInfo.h in Headers */,
08385FF610F0186000BFE07B /* SVGMarkerData.h in Headers */,
0AFDAC3D10F5448C00E1F3D2 /* PluginWidget.h in Headers */,
+ 5112247410CFB8D8008099D7 /* ThreadableWebSocketChannel.h in Headers */,
+ 5112247610CFB8E8008099D7 /* ThreadableWebSocketChannelClientWrapper.h in Headers */,
+ 5112247A10CFB8FF008099D7 /* WorkerThreadableWebSocketChannel.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -20449,6 +20467,8 @@
BC56CB2110D5AC8000A77C64 /* GeolocationController.cpp in Sources */,
08735FB810E91232006D6FAD /* SVGMarkerLayoutInfo.cpp in Sources */,
0AFDAC3B10F5448300E1F3D2 /* PluginWidgetMac.mm in Sources */,
+ 5112247210CFB8C6008099D7 /* ThreadableWebSocketChannel.cpp in Sources */,
+ 5112247810CFB8F4008099D7 /* WorkerThreadableWebSocketChannel.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/WebCore/bindings/js/JSWebSocketConstructor.h b/WebCore/bindings/js/JSWebSocketConstructor.h
index 069647a..633e612 100644
--- a/WebCore/bindings/js/JSWebSocketConstructor.h
+++ b/WebCore/bindings/js/JSWebSocketConstructor.h
@@ -31,6 +31,8 @@
#ifndef JSWebSocketConstructor_h
#define JSWebSocketConstructor_h
+#if ENABLE(WEB_SOCKETS)
+
#include "JSDOMBinding.h"
namespace WebCore {
@@ -45,6 +47,8 @@ class JSWebSocketConstructor : public DOMConstructorObject {
virtual const JSC::ClassInfo* classInfo() const { return &s_info; }
};
-} // namespace WebCore
+} // namespace WebCore
+
+#endif // ENABLE(WEB_SOCKETS)
-#endif // JSWebSocketConstructor_h
+#endif // JSWebSocketConstructor_h
diff --git a/WebCore/bindings/js/JSWorkerContextCustom.cpp b/WebCore/bindings/js/JSWorkerContextCustom.cpp
index 490d9b1..ab28674 100644
--- a/WebCore/bindings/js/JSWorkerContextCustom.cpp
+++ b/WebCore/bindings/js/JSWorkerContextCustom.cpp
@@ -32,8 +32,10 @@
#include "JSDOMBinding.h"
#include "JSDOMGlobalObject.h"
#include "JSEventListener.h"
+#include "JSEventSourceConstructor.h"
#include "JSMessageChannelConstructor.h"
#include "JSMessagePort.h"
+#include "JSWebSocketConstructor.h"
#include "JSWorkerLocation.h"
#include "JSWorkerNavigator.h"
#include "JSXMLHttpRequestConstructor.h"
@@ -43,10 +45,6 @@
#include "WorkerNavigator.h"
#include <interpreter/Interpreter.h>
-#if ENABLE(EVENTSOURCE)
-#include "JSEventSourceConstructor.h"
-#endif
-
using namespace JSC;
namespace WebCore {
@@ -93,6 +91,13 @@ JSValue JSWorkerContext::xmlHttpRequest(ExecState* exec) const
return getDOMConstructor<JSXMLHttpRequestConstructor>(exec, this);
}
+#if ENABLE(WEB_SOCKETS)
+JSValue JSWorkerContext::webSocket(ExecState* exec) const
+{
+ return getDOMConstructor<JSWebSocketConstructor>(exec, this);
+}
+#endif
+
JSValue JSWorkerContext::importScripts(ExecState* exec, const ArgList& args)
{
if (!args.size())
diff --git a/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp b/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
index 412fde0..7e3c543 100644
--- a/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
+++ b/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
@@ -319,6 +319,12 @@ v8::Handle<v8::Value> WorkerContextExecutionProxy::convertEventTargetToV8Object(
if (mp)
return convertToV8Object(V8ClassIndex::MESSAGEPORT, mp);
+#if ENABLE(WEB_SOCKETS)
+ WebSocket* webSocket = target->toWebSocket();
+ if (webSocket)
+ return convertToV8Object(V8ClassIndex::WEBSOCKET, webSocket);
+#endif
+
ASSERT_NOT_REACHED();
return v8::Handle<v8::Value>();
}
diff --git a/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp b/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp
index c9b4136..855ab7d 100644
--- a/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WebSocketCustom.cpp
@@ -93,14 +93,9 @@ v8::Handle<v8::Value> V8Custom::v8WebSocketConstructorCallback(const v8::Argumen
return throwError("Empty URL", V8Proxy::SyntaxError);
// Get the script execution context.
- ScriptExecutionContext* context = 0;
- // TODO: Workers
- if (!context) {
- Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
- if (!frame)
- return throwError("WebSocket constructor's associated frame is not available", V8Proxy::ReferenceError);
- context = frame->document();
- }
+ ScriptExecutionContext* context = getScriptExecutionContext();
+ if (!context)
+ return throwError("WebSocket constructor's associated frame is not available", V8Proxy::ReferenceError);
const KURL& url = context->completeURL(toWebCoreString(urlstring));
diff --git a/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp b/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp
index b4a6381..d257fe4 100644
--- a/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp
@@ -42,6 +42,7 @@
#include "V8Proxy.h"
#include "V8Utilities.h"
#include "V8WorkerContextEventListener.h"
+#include "WebSocket.h"
#include "WorkerContext.h"
#include "WorkerContextExecutionProxy.h"
diff --git a/WebCore/platform/CrossThreadCopier.cpp b/WebCore/platform/CrossThreadCopier.cpp
index d02da6c..c1979c4 100644
--- a/WebCore/platform/CrossThreadCopier.cpp
+++ b/WebCore/platform/CrossThreadCopier.cpp
@@ -32,6 +32,7 @@
#include "CrossThreadCopier.h"
+#include "KURL.h"
#include "PlatformString.h"
#include "ResourceError.h"
#include "ResourceRequest.h"
@@ -39,6 +40,11 @@
namespace WebCore {
+CrossThreadCopierBase<false, KURL>::Type CrossThreadCopierBase<false, KURL>::copy(const KURL& url)
+{
+ return url.copy();
+}
+
CrossThreadCopierBase<false, String>::Type CrossThreadCopierBase<false, String>::copy(const String& str)
{
return str.crossThreadString();
diff --git a/WebCore/platform/CrossThreadCopier.h b/WebCore/platform/CrossThreadCopier.h
index 2bdf57d..591a545 100644
--- a/WebCore/platform/CrossThreadCopier.h
+++ b/WebCore/platform/CrossThreadCopier.h
@@ -40,6 +40,7 @@
namespace WebCore {
+ class KURL;
class ResourceError;
class ResourceRequest;
class ResourceResponse;
@@ -94,6 +95,11 @@ namespace WebCore {
}
};
+ template<> struct CrossThreadCopierBase<false, KURL> {
+ typedef KURL Type;
+ static Type copy(const KURL&);
+ };
+
template<> struct CrossThreadCopierBase<false, String> {
typedef String Type;
static Type copy(const String&);
diff --git a/WebCore/websockets/ThreadableWebSocketChannel.cpp b/WebCore/websockets/ThreadableWebSocketChannel.cpp
new file mode 100644
index 0000000..28b9263
--- /dev/null
+++ b/WebCore/websockets/ThreadableWebSocketChannel.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEB_SOCKETS)
+
+#include "ThreadableWebSocketChannel.h"
+
+#include "PlatformString.h"
+#include "ScriptExecutionContext.h"
+#include "ThreadableWebSocketChannelClientWrapper.h"
+#include "WebSocketChannel.h"
+#include "WebSocketChannelClient.h"
+#include "WorkerContext.h"
+#include "WorkerRunLoop.h"
+#include "WorkerThread.h"
+#include "WorkerThreadableWebSocketChannel.h"
+
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+static const char webSocketChannelMode[] = "webSocketChannelMode";
+
+PassRefPtr<ThreadableWebSocketChannel> ThreadableWebSocketChannel::create(ScriptExecutionContext* context, WebSocketChannelClient* client, const KURL& url, const String& protocol)
+{
+ ASSERT(context);
+ ASSERT(client);
+
+#if ENABLE(WORKERS)
+ if (context->isWorkerContext()) {
+ WorkerContext* workerContext = static_cast<WorkerContext*>(context);
+ WorkerRunLoop& runLoop = workerContext->thread()->runLoop();
+ String mode = webSocketChannelMode;
+ mode.append(String::number(runLoop.createUniqueId()));
+ return WorkerThreadableWebSocketChannel::create(workerContext, client, mode, url, protocol);
+ }
+#endif // ENABLE(WORKERS)
+
+ ASSERT(context->isDocument());
+ return WebSocketChannel::create(context, client, url, protocol);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_SOCKETS)
diff --git a/WebCore/websockets/ThreadableWebSocketChannel.h b/WebCore/websockets/ThreadableWebSocketChannel.h
new file mode 100644
index 0000000..74ea4b4
--- /dev/null
+++ b/WebCore/websockets/ThreadableWebSocketChannel.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ThreadableWebSocketChannel_h
+#define ThreadableWebSocketChannel_h
+
+#if ENABLE(WEB_SOCKETS)
+
+#include <wtf/Noncopyable.h>
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+class KURL;
+class ScriptExecutionContext;
+class String;
+class WebSocketChannelClient;
+
+class ThreadableWebSocketChannel : public Noncopyable {
+public:
+ static PassRefPtr<ThreadableWebSocketChannel> create(ScriptExecutionContext*, WebSocketChannelClient*, const KURL&, const String& protocol);
+
+ virtual void connect() = 0;
+ virtual bool send(const String& message) = 0;
+ virtual unsigned long bufferedAmount() const = 0;
+ virtual void close() = 0;
+ virtual void disconnect() = 0; // Will suppress didClose().
+
+ void ref() { refThreadableWebSocketChannel(); }
+ void deref() { derefThreadableWebSocketChannel(); }
+
+protected:
+ virtual ~ThreadableWebSocketChannel() { }
+ virtual void refThreadableWebSocketChannel() = 0;
+ virtual void derefThreadableWebSocketChannel() = 0;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_SOCKETS)
+
+#endif // ThreadableWebSocketChannel_h
diff --git a/WebCore/websockets/ThreadableWebSocketChannelClientWrapper.h b/WebCore/websockets/ThreadableWebSocketChannelClientWrapper.h
new file mode 100644
index 0000000..8bf51fa
--- /dev/null
+++ b/WebCore/websockets/ThreadableWebSocketChannelClientWrapper.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ThreadableWebSocketChannelClientWrapper_h
+#define ThreadableWebSocketChannelClientWrapper_h
+
+#if ENABLE(WEB_SOCKETS)
+
+#include "WebSocketChannelClient.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/Threading.h>
+
+namespace WebCore {
+
+class String;
+
+class ThreadableWebSocketChannelClientWrapper : public ThreadSafeShared<ThreadableWebSocketChannelClientWrapper> {
+public:
+ static PassRefPtr<ThreadableWebSocketChannelClientWrapper> create(WebSocketChannelClient* client)
+ {
+ return adoptRef(new ThreadableWebSocketChannelClientWrapper(client));
+ }
+
+ void clearSyncMethodDone()
+ {
+ m_syncMethodDone = false;
+ }
+ void setSyncMethodDone()
+ {
+ m_syncMethodDone = true;
+ }
+
+ bool syncMethodDone() const
+ {
+ return m_syncMethodDone;
+ }
+
+ bool sent() const
+ {
+ return m_sent;
+ }
+ void setSent(bool sent)
+ {
+ m_sent = sent;
+ m_syncMethodDone = true;
+ }
+
+ unsigned long bufferedAmount() const
+ {
+ return m_bufferedAmount;
+ }
+ void setBufferedAmount(unsigned long bufferedAmount)
+ {
+ m_bufferedAmount = bufferedAmount;
+ m_syncMethodDone = true;
+ }
+
+ void clearClient()
+ {
+ m_client = 0;
+ }
+
+ void didConnect()
+ {
+ if (m_client)
+ m_client->didConnect();
+ }
+
+ void didReceiveMessage(const String& msg)
+ {
+ if (m_client)
+ m_client->didReceiveMessage(msg);
+ }
+
+ void didClose()
+ {
+ if (m_client)
+ m_client->didClose();
+ }
+
+protected:
+ ThreadableWebSocketChannelClientWrapper(WebSocketChannelClient* client)
+ : m_client(client)
+ , m_syncMethodDone(false)
+ , m_sent(false)
+ , m_bufferedAmount(0)
+ {
+ }
+
+ WebSocketChannelClient* m_client;
+ bool m_syncMethodDone;
+ bool m_sent;
+ unsigned long m_bufferedAmount;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_SOCKETS)
+
+#endif // ThreadableWebSocketChannelClientWrapper_h
diff --git a/WebCore/websockets/WebSocket.cpp b/WebCore/websockets/WebSocket.cpp
index bd62cfa..0435490 100644
--- a/WebCore/websockets/WebSocket.cpp
+++ b/WebCore/websockets/WebSocket.cpp
@@ -44,6 +44,7 @@
#include "MessageEvent.h"
#include "ScriptExecutionContext.h"
#include "StringBuilder.h"
+#include "ThreadableWebSocketChannel.h"
#include "WebSocketChannel.h"
#include <wtf/StdLibExtras.h>
@@ -148,7 +149,7 @@ void WebSocket::connect(const KURL& url, const String& protocol, ExceptionCode&
return;
}
- m_channel = WebSocketChannel::create(scriptExecutionContext(), this, m_url, m_protocol);
+ m_channel = ThreadableWebSocketChannel::create(scriptExecutionContext(), this, m_url, m_protocol);
m_channel->connect();
}
@@ -214,7 +215,6 @@ void WebSocket::didReceiveMessage(const String& msg)
if (m_state != OPEN || !scriptExecutionContext())
return;
RefPtr<MessageEvent> evt = MessageEvent::create();
- // FIXME: origin, lastEventId, source, messagePort.
evt->initMessageEvent(eventNames().messageEvent, false, false, SerializedScriptValue::create(msg), "", "", 0, 0);
dispatchEvent(evt);
}
diff --git a/WebCore/websockets/WebSocket.h b/WebCore/websockets/WebSocket.h
index 9ecbed7..18e2b25 100644
--- a/WebCore/websockets/WebSocket.h
+++ b/WebCore/websockets/WebSocket.h
@@ -46,7 +46,7 @@
namespace WebCore {
class String;
- class WebSocketChannel;
+ class ThreadableWebSocketChannel;
class WebSocket : public RefCounted<WebSocket>, public EventTarget, public ActiveDOMObject, public WebSocketChannelClient {
public:
@@ -83,20 +83,12 @@ namespace WebCore {
virtual ScriptExecutionContext* scriptExecutionContext() const;
- // ActiveDOMObject
- // virtual bool hasPendingActivity() const;
- // virtual void contextDestroyed();
- // virtual bool canSuspend() const;
- // virtual void suspend();
- // virtual void resume();
- // virtual void stop();
-
using RefCounted<WebSocket>::ref;
using RefCounted<WebSocket>::deref;
// WebSocketChannelClient
virtual void didConnect();
- virtual void didReceiveMessage(const String& msg);
+ virtual void didReceiveMessage(const String& message);
virtual void didClose();
private:
@@ -111,7 +103,7 @@ namespace WebCore {
void dispatchMessageEvent(Event*);
void dispatchCloseEvent(Event*);
- RefPtr<WebSocketChannel> m_channel;
+ RefPtr<ThreadableWebSocketChannel> m_channel;
State m_state;
KURL m_url;
@@ -119,8 +111,8 @@ namespace WebCore {
EventTargetData m_eventTargetData;
};
-} // namespace WebCore
+} // namespace WebCore
-#endif // ENABLE(WEB_SOCKETS)
+#endif // ENABLE(WEB_SOCKETS)
-#endif // WebSocket_h
+#endif // WebSocket_h
diff --git a/WebCore/websockets/WebSocketChannel.h b/WebCore/websockets/WebSocketChannel.h
index 14b1e8c..7ec826c 100644
--- a/WebCore/websockets/WebSocketChannel.h
+++ b/WebCore/websockets/WebSocketChannel.h
@@ -34,6 +34,7 @@
#if ENABLE(WEB_SOCKETS)
#include "SocketStreamHandleClient.h"
+#include "ThreadableWebSocketChannel.h"
#include "WebSocketHandshake.h"
#include <wtf/RefCounted.h>
@@ -45,16 +46,16 @@ namespace WebCore {
class SocketStreamError;
class WebSocketChannelClient;
- class WebSocketChannel : public RefCounted<WebSocketChannel>, public SocketStreamHandleClient {
+ class WebSocketChannel : public RefCounted<WebSocketChannel>, public SocketStreamHandleClient, public ThreadableWebSocketChannel {
public:
static PassRefPtr<WebSocketChannel> create(ScriptExecutionContext* context, WebSocketChannelClient* client, const KURL& url, const String& protocol) { return adoptRef(new WebSocketChannel(context, client, url, protocol)); }
virtual ~WebSocketChannel();
- void connect();
- bool send(const String& msg);
- unsigned long bufferedAmount() const;
- void close();
- void disconnect(); // Will suppress didClose().
+ virtual void connect();
+ virtual bool send(const String& message);
+ virtual unsigned long bufferedAmount() const;
+ virtual void close();
+ virtual void disconnect(); // Will suppress didClose().
virtual void didOpen(SocketStreamHandle*);
virtual void didClose(SocketStreamHandle*);
@@ -63,8 +64,15 @@ namespace WebCore {
virtual void didReceiveAuthenticationChallenge(SocketStreamHandle*, const AuthenticationChallenge&);
virtual void didCancelAuthenticationChallenge(SocketStreamHandle*, const AuthenticationChallenge&);
+ using RefCounted<WebSocketChannel>::ref;
+ using RefCounted<WebSocketChannel>::deref;
+
+ protected:
+ virtual void refThreadableWebSocketChannel() { ref(); }
+ virtual void derefThreadableWebSocketChannel() { deref(); }
+
private:
- WebSocketChannel(ScriptExecutionContext*, WebSocketChannelClient*, const KURL&, const String&);
+ WebSocketChannel(ScriptExecutionContext*, WebSocketChannelClient*, const KURL&, const String& protocol);
bool appendToBuffer(const char* data, int len);
void skipBuffer(int len);
@@ -78,8 +86,8 @@ namespace WebCore {
unsigned long m_unhandledBufferSize;
};
-} // namespace WebCore
+} // namespace WebCore
-#endif // ENABLE(WEB_SOCKETS)
+#endif // ENABLE(WEB_SOCKETS)
-#endif // WebSocketChannel_h
+#endif // WebSocketChannel_h
diff --git a/WebCore/websockets/WebSocketChannelClient.h b/WebCore/websockets/WebSocketChannelClient.h
index 463cada..163070f 100644
--- a/WebCore/websockets/WebSocketChannelClient.h
+++ b/WebCore/websockets/WebSocketChannelClient.h
@@ -46,8 +46,8 @@ namespace WebCore {
WebSocketChannelClient() { }
};
-} // namespace WebCore
+} // namespace WebCore
-#endif // ENABLE(WEB_SOCKETS)
+#endif // ENABLE(WEB_SOCKETS)
-#endif // WebSocketChannelClient_h
+#endif // WebSocketChannelClient_h
diff --git a/WebCore/websockets/WebSocketHandshake.h b/WebCore/websockets/WebSocketHandshake.h
index d5dbe68..bda320a 100644
--- a/WebCore/websockets/WebSocketHandshake.h
+++ b/WebCore/websockets/WebSocketHandshake.h
@@ -106,8 +106,8 @@ namespace WebCore {
String m_setCookie2;
};
-} // namespace WebCore
+} // namespace WebCore
-#endif // ENABLE(WEB_SOCKETS)
+#endif // ENABLE(WEB_SOCKETS)
-#endif // WebSocketHandshake_h
+#endif // WebSocketHandshake_h
diff --git a/WebCore/websockets/WorkerThreadableWebSocketChannel.cpp b/WebCore/websockets/WorkerThreadableWebSocketChannel.cpp
new file mode 100644
index 0000000..b15c151
--- /dev/null
+++ b/WebCore/websockets/WorkerThreadableWebSocketChannel.cpp
@@ -0,0 +1,360 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEB_SOCKETS) && ENABLE(WORKERS)
+
+#include "WorkerThreadableWebSocketChannel.h"
+
+#include "GenericWorkerTask.h"
+#include "PlatformString.h"
+#include "ScriptExecutionContext.h"
+#include "ThreadableWebSocketChannelClientWrapper.h"
+#include "WebSocketChannel.h"
+#include "WebSocketChannelClient.h"
+#include "WorkerContext.h"
+#include "WorkerLoaderProxy.h"
+#include "WorkerRunLoop.h"
+#include "WorkerThread.h"
+
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+WorkerThreadableWebSocketChannel::WorkerThreadableWebSocketChannel(WorkerContext* context, WebSocketChannelClient* client, const String& taskMode, const KURL& url, const String& protocol)
+ : m_workerContext(context)
+ , m_workerClientWrapper(ThreadableWebSocketChannelClientWrapper::create(client))
+ , m_bridge(new Bridge(m_workerClientWrapper, m_workerContext, taskMode, url, protocol))
+{
+}
+
+WorkerThreadableWebSocketChannel::~WorkerThreadableWebSocketChannel()
+{
+ if (m_bridge)
+ m_bridge->disconnect();
+}
+
+void WorkerThreadableWebSocketChannel::connect()
+{
+ if (m_bridge)
+ m_bridge->connect();
+}
+
+bool WorkerThreadableWebSocketChannel::send(const String& message)
+{
+ if (!m_bridge)
+ return false;
+ return m_bridge->send(message);
+}
+
+unsigned long WorkerThreadableWebSocketChannel::bufferedAmount() const
+{
+ if (!m_bridge)
+ return 0;
+ return m_bridge->bufferedAmount();
+}
+
+void WorkerThreadableWebSocketChannel::close()
+{
+ if (!m_bridge)
+ m_bridge->close();
+}
+
+void WorkerThreadableWebSocketChannel::disconnect()
+{
+ m_bridge->disconnect();
+ m_bridge.clear();
+}
+
+WorkerThreadableWebSocketChannel::Peer::Peer(RefPtr<ThreadSafeShared<ThreadableWebSocketChannelClientWrapper> > clientWrapper, WorkerLoaderProxy& loaderProxy, ScriptExecutionContext* context, const String& taskMode, const KURL& url, const String& protocol)
+ : m_workerClientWrapper(clientWrapper)
+ , m_loaderProxy(loaderProxy)
+ , m_mainWebSocketChannel(WebSocketChannel::create(context, this, url, protocol))
+ , m_taskMode(taskMode)
+{
+ ASSERT(isMainThread());
+}
+
+WorkerThreadableWebSocketChannel::Peer::~Peer()
+{
+ ASSERT(isMainThread());
+ if (m_mainWebSocketChannel)
+ m_mainWebSocketChannel->disconnect();
+}
+
+void WorkerThreadableWebSocketChannel::Peer::connect()
+{
+ ASSERT(isMainThread());
+ if (!m_mainWebSocketChannel)
+ return;
+ m_mainWebSocketChannel->connect();
+}
+
+static void workerContextDidSend(ScriptExecutionContext* context, RefPtr<ThreadSafeShared<ThreadableWebSocketChannelClientWrapper> > workerClientWrapper, bool sent)
+{
+ ASSERT_UNUSED(context, context->isWorkerContext());
+ static_cast<ThreadableWebSocketChannelClientWrapper*>(workerClientWrapper.get())->setSent(sent);
+}
+
+void WorkerThreadableWebSocketChannel::Peer::send(const String& message)
+{
+ ASSERT(isMainThread());
+ if (!m_mainWebSocketChannel || !m_workerClientWrapper)
+ return;
+ bool sent = m_mainWebSocketChannel->send(message);
+ m_loaderProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidSend, m_workerClientWrapper, sent), m_taskMode);
+}
+
+static void workerContextDidGetBufferedAmount(ScriptExecutionContext* context, RefPtr<ThreadSafeShared<ThreadableWebSocketChannelClientWrapper> > workerClientWrapper, unsigned long bufferedAmount)
+{
+ ASSERT_UNUSED(context, context->isWorkerContext());
+ static_cast<ThreadableWebSocketChannelClientWrapper*>(workerClientWrapper.get())->setBufferedAmount(bufferedAmount);
+}
+
+void WorkerThreadableWebSocketChannel::Peer::bufferedAmount()
+{
+ ASSERT(isMainThread());
+ if (!m_mainWebSocketChannel || !m_workerClientWrapper)
+ return;
+ unsigned long bufferedAmount = m_mainWebSocketChannel->bufferedAmount();
+ m_loaderProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidGetBufferedAmount, m_workerClientWrapper, bufferedAmount), m_taskMode);
+}
+
+void WorkerThreadableWebSocketChannel::Peer::close()
+{
+ ASSERT(isMainThread());
+ if (!m_mainWebSocketChannel)
+ return;
+ m_mainWebSocketChannel->close();
+ m_mainWebSocketChannel = 0;
+}
+
+void WorkerThreadableWebSocketChannel::Peer::disconnect()
+{
+ ASSERT(isMainThread());
+ if (!m_mainWebSocketChannel)
+ return;
+ m_mainWebSocketChannel->disconnect();
+ m_mainWebSocketChannel = 0;
+}
+
+static void workerContextDidConnect(ScriptExecutionContext* context, RefPtr<ThreadSafeShared<ThreadableWebSocketChannelClientWrapper> > workerClientWrapper)
+{
+ ASSERT_UNUSED(context, context->isWorkerContext());
+ static_cast<ThreadableWebSocketChannelClientWrapper*>(workerClientWrapper.get())->didConnect();
+}
+
+void WorkerThreadableWebSocketChannel::Peer::didConnect()
+{
+ ASSERT(isMainThread());
+ m_loaderProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidConnect, m_workerClientWrapper), m_taskMode);
+}
+
+static void workerContextDidReceiveMessage(ScriptExecutionContext* context, RefPtr<ThreadSafeShared<ThreadableWebSocketChannelClientWrapper> > workerClientWrapper, const String& message)
+{
+ ASSERT_UNUSED(context, context->isWorkerContext());
+ static_cast<ThreadableWebSocketChannelClientWrapper*>(workerClientWrapper.get())->didReceiveMessage(message);
+}
+
+void WorkerThreadableWebSocketChannel::Peer::didReceiveMessage(const String& message)
+{
+ ASSERT(isMainThread());
+ m_loaderProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidReceiveMessage, m_workerClientWrapper, message), m_taskMode);
+}
+
+static void workerContextDidClose(ScriptExecutionContext* context, RefPtr<ThreadSafeShared<ThreadableWebSocketChannelClientWrapper> > workerClientWrapper)
+{
+ ASSERT_UNUSED(context, context->isWorkerContext());
+ static_cast<ThreadableWebSocketChannelClientWrapper*>(workerClientWrapper.get())->didClose();
+}
+
+void WorkerThreadableWebSocketChannel::Peer::didClose()
+{
+ ASSERT(isMainThread());
+ m_mainWebSocketChannel = 0;
+ m_loaderProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidClose, m_workerClientWrapper), m_taskMode);
+}
+
+void WorkerThreadableWebSocketChannel::Bridge::setWebSocketChannel(ScriptExecutionContext* context, Bridge* thisPtr, Peer* peer, RefPtr<ThreadSafeShared<ThreadableWebSocketChannelClientWrapper> > workerClientWrapper)
+{
+ ASSERT_UNUSED(context, context->isWorkerContext());
+ thisPtr->m_peer = peer;
+ static_cast<ThreadableWebSocketChannelClientWrapper*>(workerClientWrapper.get())->setSyncMethodDone();
+}
+
+void WorkerThreadableWebSocketChannel::Bridge::mainThreadCreateWebSocketChannel(ScriptExecutionContext* context, Bridge* thisPtr, RefPtr<ThreadSafeShared<ThreadableWebSocketChannelClientWrapper> > clientWrapper, const String& taskMode, const KURL& url, const String& protocol)
+{
+ ASSERT(isMainThread());
+ ASSERT_UNUSED(context, context->isDocument());
+
+ Peer* peer = Peer::create(clientWrapper, thisPtr->m_loaderProxy, context, taskMode, url, protocol);
+ thisPtr->m_loaderProxy.postTaskForModeToWorkerContext(createCallbackTask(&Bridge::setWebSocketChannel, thisPtr, peer, clientWrapper), taskMode);
+}
+
+WorkerThreadableWebSocketChannel::Bridge::Bridge(PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, PassRefPtr<WorkerContext> workerContext, const String& taskMode, const KURL& url, const String& protocol)
+ : m_workerClientWrapper(workerClientWrapper)
+ , m_workerContext(workerContext)
+ , m_loaderProxy(m_workerContext->thread()->workerLoaderProxy())
+ , m_taskMode(taskMode)
+ , m_peer(0)
+{
+ ASSERT(context->isWorkerContext());
+ ASSERT(m_workerClientWrapper.get());
+ setMethodNotCompleted();
+ m_loaderProxy.postTaskToLoader(createCallbackTask(&Bridge::mainThreadCreateWebSocketChannel, this, m_workerClientWrapper, m_taskMode, url, protocol));
+ waitForMethodCompletion();
+ ASSERT(m_peer);
+}
+
+WorkerThreadableWebSocketChannel::Bridge::~Bridge()
+{
+ disconnect();
+}
+
+void WorkerThreadableWebSocketChannel::mainThreadConnect(ScriptExecutionContext* context, Peer* peer)
+{
+ ASSERT(isMainThread());
+ ASSERT_UNUSED(context, context->isDocument());
+ ASSERT(peer);
+
+ peer->connect();
+}
+
+void WorkerThreadableWebSocketChannel::Bridge::connect()
+{
+ ASSERT(m_workerClientWrapper);
+ ASSERT(m_peer);
+ m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadConnect, m_peer));
+}
+
+void WorkerThreadableWebSocketChannel::mainThreadSend(ScriptExecutionContext* context, Peer* peer, const String& message)
+{
+ ASSERT(isMainThread());
+ ASSERT_UNUSED(context, context->isDocument());
+ ASSERT(peer);
+
+ peer->send(message);
+}
+
+bool WorkerThreadableWebSocketChannel::Bridge::send(const String& message)
+{
+ if (!m_workerClientWrapper)
+ return false;
+ ASSERT(m_peer);
+ setMethodNotCompleted();
+ m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadSend, m_peer, message));
+ waitForMethodCompletion();
+ ThreadableWebSocketChannelClientWrapper* clientWrapper = static_cast<ThreadableWebSocketChannelClientWrapper*>(m_workerClientWrapper.get());
+ return clientWrapper && clientWrapper->sent();
+}
+
+void WorkerThreadableWebSocketChannel::mainThreadBufferedAmount(ScriptExecutionContext* context, Peer* peer)
+{
+ ASSERT(isMainThread());
+ ASSERT_UNUSED(context, context->isDocument());
+ ASSERT(peer);
+
+ peer->bufferedAmount();
+}
+
+unsigned long WorkerThreadableWebSocketChannel::Bridge::bufferedAmount()
+{
+ if (!m_workerClientWrapper)
+ return 0;
+ ASSERT(m_peer);
+ setMethodNotCompleted();
+ m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadBufferedAmount, m_peer));
+ waitForMethodCompletion();
+ ThreadableWebSocketChannelClientWrapper* clientWrapper = static_cast<ThreadableWebSocketChannelClientWrapper*>(m_workerClientWrapper.get());
+ if (clientWrapper)
+ return clientWrapper->bufferedAmount();
+ return 0;
+}
+
+void WorkerThreadableWebSocketChannel::mainThreadClose(ScriptExecutionContext* context, Peer* peer)
+{
+ ASSERT(isMainThread());
+ ASSERT_UNUSED(context, context->isDocument());
+ ASSERT(peer);
+
+ peer->close();
+}
+
+void WorkerThreadableWebSocketChannel::Bridge::close()
+{
+ ASSERT(m_peer);
+ m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadClose, m_peer));
+}
+
+void WorkerThreadableWebSocketChannel::mainThreadDestroy(ScriptExecutionContext* context, Peer* peer)
+{
+ ASSERT(isMainThread());
+ ASSERT_UNUSED(context, context->isDocument());
+ ASSERT(peer);
+
+ delete peer;
+}
+
+void WorkerThreadableWebSocketChannel::Bridge::disconnect()
+{
+ clearClientWrapper();
+ if (m_peer) {
+ Peer* peer = m_peer;
+ m_peer = 0;
+ m_loaderProxy.postTaskToLoader(createCallbackTask(&mainThreadDestroy, peer));
+ }
+}
+
+void WorkerThreadableWebSocketChannel::Bridge::clearClientWrapper()
+{
+ static_cast<ThreadableWebSocketChannelClientWrapper*>(m_workerClientWrapper.get())->clearClient();
+}
+
+void WorkerThreadableWebSocketChannel::Bridge::setMethodNotCompleted()
+{
+ ASSERT(m_workerClientWrapper);
+ static_cast<ThreadableWebSocketChannelClientWrapper*>(m_workerClientWrapper.get())->clearSyncMethodDone();
+}
+
+void WorkerThreadableWebSocketChannel::Bridge::waitForMethodCompletion()
+{
+ WorkerRunLoop& runLoop = m_workerContext->thread()->runLoop();
+ MessageQueueWaitResult result = MessageQueueMessageReceived;
+ ThreadableWebSocketChannelClientWrapper* clientWrapper = static_cast<ThreadableWebSocketChannelClientWrapper*>(m_workerClientWrapper.get());
+ while (clientWrapper && !clientWrapper->syncMethodDone() && result != MessageQueueTerminated) {
+ result = runLoop.runInMode(m_workerContext.get(), m_taskMode);
+ clientWrapper = static_cast<ThreadableWebSocketChannelClientWrapper*>(m_workerClientWrapper.get());
+ }
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_SOCKETS)
diff --git a/WebCore/websockets/WorkerThreadableWebSocketChannel.h b/WebCore/websockets/WorkerThreadableWebSocketChannel.h
new file mode 100644
index 0000000..35bebc3
--- /dev/null
+++ b/WebCore/websockets/WorkerThreadableWebSocketChannel.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WorkerThreadableWebSocketChannel_h
+#define WorkerThreadableWebSocketChannel_h
+
+#if ENABLE(WEB_SOCKETS) && ENABLE(WORKERS)
+
+#include "PlatformString.h"
+#include "ThreadableWebSocketChannel.h"
+#include "WebSocketChannelClient.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Threading.h>
+
+namespace WebCore {
+
+class KURL;
+class ScriptExecutionContext;
+class ThreadableWebSocketChannelClientWrapper;
+class WorkerContext;
+class WorkerLoaderProxy;
+class WorkerRunLoop;
+
+class WorkerThreadableWebSocketChannel : public RefCounted<WorkerThreadableWebSocketChannel>, public ThreadableWebSocketChannel {
+public:
+ static PassRefPtr<ThreadableWebSocketChannel> create(WorkerContext* workerContext, WebSocketChannelClient* client, const String& taskMode, const KURL& url, const String& protocol)
+ {
+ return adoptRef(new WorkerThreadableWebSocketChannel(workerContext, client, taskMode, url, protocol));
+ }
+ virtual ~WorkerThreadableWebSocketChannel();
+
+ virtual void connect();
+ virtual bool send(const String& message);
+ virtual unsigned long bufferedAmount() const;
+ virtual void close();
+ virtual void disconnect(); // Will suppress didClose().
+
+ 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 {
+ public:
+ static Peer* create(RefPtr<ThreadSafeShared<ThreadableWebSocketChannelClientWrapper> > clientWrapper, WorkerLoaderProxy& loaderProxy, ScriptExecutionContext* context, const String& taskMode, const KURL& url, const String& protocol)
+ {
+ return new Peer(clientWrapper, loaderProxy, context, taskMode, url, protocol);
+ }
+ ~Peer();
+
+ void connect();
+ void send(const String& message);
+ void bufferedAmount();
+ void close();
+ void disconnect();
+
+ virtual void didConnect();
+ virtual void didReceiveMessage(const String& message);
+ virtual void didClose();
+
+ private:
+ Peer(RefPtr<ThreadSafeShared<ThreadableWebSocketChannelClientWrapper> >, WorkerLoaderProxy&, ScriptExecutionContext*, const String& taskMode, const KURL&, const String& protocol);
+
+ RefPtr<ThreadSafeShared<ThreadableWebSocketChannelClientWrapper> > m_workerClientWrapper;
+ WorkerLoaderProxy& m_loaderProxy;
+ RefPtr<ThreadableWebSocketChannel> m_mainWebSocketChannel;
+ String m_taskMode;
+ };
+
+ // Bridge for Peer. Running on the worker thread.
+ class Bridge : public RefCounted<Bridge> {
+ public:
+ Bridge(PassRefPtr<ThreadableWebSocketChannelClientWrapper>, PassRefPtr<WorkerContext>, const String& taskMode, const KURL&, const String& protocol);
+ ~Bridge();
+ void connect();
+ bool send(const String& message);
+ unsigned long bufferedAmount();
+ void close();
+ void disconnect();
+
+ using RefCounted<Bridge>::ref;
+ using RefCounted<Bridge>::deref;
+
+ private:
+ static void setWebSocketChannel(ScriptExecutionContext*, Bridge* thisPtr, Peer*, RefPtr<ThreadSafeShared<ThreadableWebSocketChannelClientWrapper> >);
+
+ // Executed on the main thread to create a Peer for this bridge.
+ static void mainThreadCreateWebSocketChannel(ScriptExecutionContext*, Bridge* thisPtr, RefPtr<ThreadSafeShared<ThreadableWebSocketChannelClientWrapper> >, const String& taskMode, const KURL&, const String& protocol);
+
+ // Executed on the worker context's thread.
+ void clearClientWrapper();
+
+ void setMethodNotCompleted();
+ void waitForMethodCompletion();
+
+ RefPtr<ThreadSafeShared<ThreadableWebSocketChannelClientWrapper> > m_workerClientWrapper;
+ RefPtr<WorkerContext> m_workerContext;
+ WorkerLoaderProxy& m_loaderProxy;
+ String m_taskMode;
+ Peer* m_peer;
+ };
+
+ WorkerThreadableWebSocketChannel(WorkerContext*, WebSocketChannelClient*, const String& taskMode, const KURL&, const String& protocol);
+
+ static void mainThreadConnect(ScriptExecutionContext*, Peer*);
+ static void mainThreadSend(ScriptExecutionContext*, Peer*, const String& message);
+ static void mainThreadBufferedAmount(ScriptExecutionContext*, Peer*);
+ static void mainThreadClose(ScriptExecutionContext*, Peer*);
+ static void mainThreadDestroy(ScriptExecutionContext*, Peer*);
+
+ RefPtr<WorkerContext> m_workerContext;
+ RefPtr<ThreadableWebSocketChannelClientWrapper> m_workerClientWrapper;
+ RefPtr<Bridge> m_bridge;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_SOCKETS)
+
+#endif // WorkerThreadableWebSocketChannel_h
diff --git a/WebCore/workers/WorkerContext.idl b/WebCore/workers/WorkerContext.idl
index ffbf9cc..bce4f53 100644
--- a/WebCore/workers/WorkerContext.idl
+++ b/WebCore/workers/WorkerContext.idl
@@ -87,6 +87,9 @@ module threads {
attribute [JSCCustomGetter] EventSourceConstructor EventSource;
#endif
attribute [JSCCustomGetter] XMLHttpRequestConstructor XMLHttpRequest;
+#if defined(ENABLE_WEB_SOCKETS) && ENABLE_WEB_SOCKETS
+ attribute [JSCCustomGetter,EnabledAtRuntime] WebSocketConstructor WebSocket; // Usable with the new operator
+#endif
};
}
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list