WebCore:
authorlevin@chromium.org <levin@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Mar 2009 22:29:46 +0000 (22:29 +0000)
committerlevin@chromium.org <levin@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Mar 2009 22:29:46 +0000 (22:29 +0000)
2009-03-04  David Levin  <levin@chromium.org>

        Reviewed by Alexey Proskuryakov.

        Bug 24330: Sync xhr in workers should send an abort exception when the worker is terminated.
        <https://bugs.webkit.org/show_bug.cgi?id=24330>

        Test: http/tests/xmlhttprequest/workers/abort-exception-assert.html

        * dom/ExceptionCode.cpp:
        (WebCore::xmlHttpRequestExceptionNames):
        Added missing ABORT_ERR whose absence caused an assert.

        * loader/WorkerThreadableLoader.cpp:
        (WebCore::WorkerThreadableLoader::loadResourceSynchronously):
        (WebCore::WorkerThreadableLoader::MainThreadBridge::cancel):
        Add more logic to handle the termination case for sync xhr.

LayoutTests:

2009-03-04  David Levin  <levin@chromium.org>

        Reviewed by Alexey Proskuryakov.

        Bug 24330: Sync xhr in workers should send an abort exception when the worker is terminated.
        <https://bugs.webkit.org/show_bug.cgi?id=24330>

        Added test to verify to terminate a worker while it is doing a synchronous xhr.
        It does not verify that the exception is a ABORT_ERR because I couldn't figure out a way
        to actually do this.

        * http/tests/xmlhttprequest/workers/abort-exception-assert-expected.txt: Added.
        * http/tests/xmlhttprequest/workers/abort-exception-assert.html: Added.
        * http/tests/xmlhttprequest/workers/resources/endless-response.php: Copied from LayoutTests/http/tests/xmlhttprequest/resources/endlessxml.php.
        * http/tests/xmlhttprequest/workers/resources/endless-sync-xhr.js: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@41433 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/http/tests/xmlhttprequest/workers/abort-exception-assert-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/xmlhttprequest/workers/abort-exception-assert.html [new file with mode: 0644]
LayoutTests/http/tests/xmlhttprequest/workers/resources/endless-response.php [new file with mode: 0755]
LayoutTests/http/tests/xmlhttprequest/workers/resources/endless-sync-xhr.js [new file with mode: 0644]
WebCore/ChangeLog
WebCore/dom/ExceptionCode.cpp
WebCore/loader/WorkerThreadableLoader.cpp

index 321670fdb4f084005ed1d06ebb1b7f87c92ee229..0c417064e8e2b9eb7e23933bb9c562b7d32a37fb 100644 (file)
@@ -1,3 +1,19 @@
+2009-03-04  David Levin  <levin@chromium.org>
+
+        Reviewed by Alexey Proskuryakov.
+
+        Bug 24330: Sync xhr in workers should send an abort exception when the worker is terminated.
+        <https://bugs.webkit.org/show_bug.cgi?id=24330>
+
+        Added test to verify to terminate a worker while it is doing a synchronous xhr.
+        It does not verify that the exception is a ABORT_ERR because I couldn't figure out a way
+        to actually do this.
+
+        * http/tests/xmlhttprequest/workers/abort-exception-assert-expected.txt: Added.
+        * http/tests/xmlhttprequest/workers/abort-exception-assert.html: Added.
+        * http/tests/xmlhttprequest/workers/resources/endless-response.php: Copied from LayoutTests/http/tests/xmlhttprequest/resources/endlessxml.php.
+        * http/tests/xmlhttprequest/workers/resources/endless-sync-xhr.js: Added.
+
 2009-03-04  Eric Carlson  <eric.carlson@apple.com>
 
         Reviewed by Antti Koivisto.
diff --git a/LayoutTests/http/tests/xmlhttprequest/workers/abort-exception-assert-expected.txt b/LayoutTests/http/tests/xmlhttprequest/workers/abort-exception-assert-expected.txt
new file mode 100644 (file)
index 0000000..41ce0e9
--- /dev/null
@@ -0,0 +1,5 @@
+XmlHttpRequest abort exception shouldn't assert.
+
+On success, you should see a single PASS below.
+
+PASS
diff --git a/LayoutTests/http/tests/xmlhttprequest/workers/abort-exception-assert.html b/LayoutTests/http/tests/xmlhttprequest/workers/abort-exception-assert.html
new file mode 100644 (file)
index 0000000..c8dad3d
--- /dev/null
@@ -0,0 +1,38 @@
+<html>
+<body>
+<p>XmlHttpRequest abort exception shouldn't assert.</p>
+<p>On success, you should see a single PASS below.</p>
+<script>
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
+
+    var console_messages = document.createElement("ol");
+    document.body.appendChild(console_messages);
+
+    function log(message)
+    {
+        var item = document.createElement("li");
+        item.appendChild(document.createTextNode(message));
+        console_messages.appendChild(item);
+    }
+
+    var worker = new Worker('resources/endless-sync-xhr.js');
+    worker.onmessage = function(evt)
+    {
+        setTimeout("terminateWorkerAndFinish();", 100);
+    }
+
+    function terminateWorkerAndFinish()
+    {
+        // This is an (unlikley) race condition here in that the worker may not have started
+        // the sync xhr call at this point, but it has been greatly lessened by the 100ms delay.
+        worker.terminate();
+        log("PASS");
+        if (window.layoutTestController)
+            layoutTestController.notifyDone();
+    }
+</script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/xmlhttprequest/workers/resources/endless-response.php b/LayoutTests/http/tests/xmlhttprequest/workers/resources/endless-response.php
new file mode 100755 (executable)
index 0000000..b720ba1
--- /dev/null
@@ -0,0 +1,3 @@
+<?php
+sleep(10);
+?>
diff --git a/LayoutTests/http/tests/xmlhttprequest/workers/resources/endless-sync-xhr.js b/LayoutTests/http/tests/xmlhttprequest/workers/resources/endless-sync-xhr.js
new file mode 100644 (file)
index 0000000..5f776ef
--- /dev/null
@@ -0,0 +1,7 @@
+postMessage("START");
+xhr = new XMLHttpRequest;
+xhr.open("GET", "endless-response.php", false);
+try {
+    xhr.send();
+} catch (e) {
+}
index 9c5b8ce825fb8a623dece7a5cec992ed5eb8dffc..0928b64d857c9aaaece8673300f71bf7c69b2ec9 100644 (file)
@@ -1,3 +1,21 @@
+2009-03-04  David Levin  <levin@chromium.org>
+
+        Reviewed by Alexey Proskuryakov.
+
+        Bug 24330: Sync xhr in workers should send an abort exception when the worker is terminated.
+        <https://bugs.webkit.org/show_bug.cgi?id=24330>
+
+        Test: http/tests/xmlhttprequest/workers/abort-exception-assert.html
+
+        * dom/ExceptionCode.cpp:
+        (WebCore::xmlHttpRequestExceptionNames):
+        Added missing ABORT_ERR whose absence caused an assert.
+
+        * loader/WorkerThreadableLoader.cpp:
+        (WebCore::WorkerThreadableLoader::loadResourceSynchronously):
+        (WebCore::WorkerThreadableLoader::MainThreadBridge::cancel):
+        Add more logic to handle the termination case for sync xhr.
+
 2009-03-04  Eric Carlson  <eric.carlson@apple.com>
 
         Reviewed by Antti Koivisto.
index fa0a7a738d25e0247e343322b08f5301c059f96b..8ce1643bf71266cc859234633d4c9d58787830af 100644 (file)
@@ -71,7 +71,8 @@ static const char* const eventExceptionNames[] = {
 };
 
 static const char* const xmlHttpRequestExceptionNames[] = {
-    "NETWORK_ERR"
+    "NETWORK_ERR",
+    "ABORT_ERR"
 };
 
 #if ENABLE(XPATH)
index 7d6e7cf9d8828175828f4b91807b3194d42f03c9..731ffcbe5945d92c3616149a41c7158d0c3d5e8b 100644 (file)
@@ -78,8 +78,13 @@ void WorkerThreadableLoader::loadResourceSynchronously(WorkerContext* workerCont
 
     ContentSniff contentSniff = request.url().isLocalFile() ? SniffContent : DoNotSniffContent;
     RefPtr<WorkerThreadableLoader> loader = WorkerThreadableLoader::create(workerContext, &client, mode, request, DoNotSendLoadCallbacks, contentSniff);
-    while (!loader->done())
-        runLoop.runInMode(workerContext, mode);
+
+    MessageQueueWaitResult result = MessageQueueMessageReceived;
+    while (!loader->done() && result != MessageQueueTerminated)
+        result = runLoop.runInMode(workerContext, mode);
+
+    if (!loader->done() && result == MessageQueueTerminated)
+        loader->cancel();
 }
 
 void WorkerThreadableLoader::cancel()
@@ -154,6 +159,14 @@ void WorkerThreadableLoader::MainThreadBridge::mainThreadCancel(ScriptExecutionC
 void WorkerThreadableLoader::MainThreadBridge::cancel()
 {
     m_messagingProxy.postTaskToWorkerObject(createCallbackTask(&MainThreadBridge::mainThreadCancel, this));
+    ThreadableLoaderClientWrapper* clientWrapper = static_cast<ThreadableLoaderClientWrapper*>(m_workerClientWrapper.get());
+    if (!clientWrapper->done()) {
+        // If the client hasn't reached a termination state, then transition it by sending a cancellation error.
+        // Note: no more client callbacks will be done after this method -- the clearClientWrapper() call ensures that.
+        ResourceError error(String(), 0, String(), String());
+        error.setIsCancellation(true);
+        clientWrapper->didFail(error);
+    }
     clearClientWrapper();
 }