gecko/dom/workers/XMLHttpRequestPrivate.cpp

1764 lines
45 KiB
C++
Raw Normal View History

Bug 649537 - 'Workers: Make one OS thread and JS runtime per worker, and lose XPConnect'. r=sicking+mrbkap. * * * Bug 649537 - 'Workers: Make one OS thread and JS runtime per worker, and lose XPConnect'. r=sicking+mrbkap. Add workaround for bug 666963. --HG-- rename : dom/src/threads/Makefile.in => dom/workers/Makefile.in rename : dom/src/threads/test/Makefile.in => dom/workers/test/Makefile.in rename : dom/src/threads/test/WorkerTest.jsm => dom/workers/test/WorkerTest.jsm rename : dom/src/threads/test/WorkerTest_badworker.js => dom/workers/test/WorkerTest_badworker.js rename : dom/src/threads/test/WorkerTest_subworker.js => dom/workers/test/WorkerTest_subworker.js rename : dom/src/threads/test/WorkerTest_worker.js => dom/workers/test/WorkerTest_worker.js rename : dom/src/threads/test/atob_worker.js => dom/workers/test/atob_worker.js rename : dom/src/threads/test/chromeWorker_subworker.js => dom/workers/test/chromeWorker_subworker.js rename : dom/src/threads/test/chromeWorker_worker.js => dom/workers/test/chromeWorker_worker.js rename : dom/src/threads/test/closeOnGC_server.sjs => dom/workers/test/closeOnGC_server.sjs rename : dom/src/threads/test/closeOnGC_worker.js => dom/workers/test/closeOnGC_worker.js rename : dom/src/threads/test/close_worker.js => dom/workers/test/close_worker.js rename : dom/src/threads/test/fibonacci_worker.js => dom/workers/test/fibonacci_worker.js rename : dom/src/threads/test/importScripts_worker.js => dom/workers/test/importScripts_worker.js rename : dom/src/threads/test/importScripts_worker_imported1.js => dom/workers/test/importScripts_worker_imported1.js rename : dom/src/threads/test/importScripts_worker_imported2.js => dom/workers/test/importScripts_worker_imported2.js rename : dom/src/threads/test/importScripts_worker_imported3.js => dom/workers/test/importScripts_worker_imported3.js rename : dom/src/threads/test/importScripts_worker_imported4.js => dom/workers/test/importScripts_worker_imported4.js rename : dom/src/threads/test/json_worker.js => dom/workers/test/json_worker.js rename : dom/src/threads/test/location_worker.js => dom/workers/test/location_worker.js rename : dom/src/threads/test/longThread_worker.js => dom/workers/test/longThread_worker.js rename : dom/src/threads/test/navigator_worker.js => dom/workers/test/navigator_worker.js rename : dom/src/threads/test/newError_worker.js => dom/workers/test/newError_worker.js rename : dom/src/threads/test/recursion_worker.js => dom/workers/test/recursion_worker.js rename : dom/src/threads/test/relativeLoad_import.js => dom/workers/test/relativeLoad_import.js rename : dom/src/threads/test/relativeLoad_sub_import.js => dom/workers/test/relativeLoad_sub_import.js rename : dom/src/threads/test/relativeLoad_sub_worker.js => dom/workers/test/relativeLoad_sub_worker.js rename : dom/src/threads/test/relativeLoad_sub_worker2.js => dom/workers/test/relativeLoad_sub_worker2.js rename : dom/src/threads/test/relativeLoad_worker.js => dom/workers/test/relativeLoad_worker.js rename : dom/src/threads/test/relativeLoad_worker2.js => dom/workers/test/relativeLoad_worker2.js rename : dom/src/threads/test/simpleThread_worker.js => dom/workers/test/simpleThread_worker.js rename : dom/src/threads/test/suspend_iframe.html => dom/workers/test/suspend_iframe.html rename : dom/src/threads/test/suspend_worker.js => dom/workers/test/suspend_worker.js rename : dom/src/threads/test/terminate_worker.js => dom/workers/test/terminate_worker.js rename : dom/src/threads/test/testXHR.txt => dom/workers/test/testXHR.txt rename : dom/src/threads/test/test_404.html => dom/workers/test/test_404.html rename : dom/src/threads/test/test_atob.html => dom/workers/test/test_atob.html rename : dom/src/threads/test/test_chromeWorker.html => dom/workers/test/test_chromeWorker.html rename : dom/src/threads/test/test_chromeWorker.xul => dom/workers/test/test_chromeWorker.xul rename : dom/src/threads/test/test_chromeWorkerJSM.xul => dom/workers/test/test_chromeWorkerJSM.xul rename : dom/src/threads/test/test_close.html => dom/workers/test/test_close.html rename : dom/src/threads/test/test_closeOnGC.html => dom/workers/test/test_closeOnGC.html rename : dom/src/threads/test/test_errorPropagation.html => dom/workers/test/test_errorPropagation.html rename : dom/src/threads/test/test_fibonacci.html => dom/workers/test/test_fibonacci.html rename : dom/src/threads/test/test_importScripts.html => dom/workers/test/test_importScripts.html rename : dom/src/threads/test/test_json.html => dom/workers/test/test_json.html rename : dom/src/threads/test/test_location.html => dom/workers/test/test_location.html rename : dom/src/threads/test/test_longThread.html => dom/workers/test/test_longThread.html rename : dom/src/threads/test/test_navigator.html => dom/workers/test/test_navigator.html rename : dom/src/threads/test/test_newError.html => dom/workers/test/test_newError.html rename : dom/src/threads/test/test_recursion.html => dom/workers/test/test_recursion.html rename : dom/src/threads/test/test_relativeLoad.html => dom/workers/test/test_relativeLoad.html rename : dom/src/threads/test/test_simpleThread.html => dom/workers/test/test_simpleThread.html rename : dom/src/threads/test/test_suspend.html => dom/workers/test/test_suspend.html rename : dom/src/threads/test/test_terminate.html => dom/workers/test/test_terminate.html rename : dom/src/threads/test/test_threadErrors.html => dom/workers/test/test_threadErrors.html rename : dom/src/threads/test/test_threadTimeouts.html => dom/workers/test/test_threadTimeouts.html rename : dom/src/threads/test/test_throwingOnerror.html => dom/workers/test/test_throwingOnerror.html rename : dom/src/threads/test/test_xhr.html => dom/workers/test/test_xhr.html rename : dom/src/threads/test/test_xhrAbort.html => dom/workers/test/test_xhrAbort.html rename : dom/src/threads/test/threadErrors_worker1.js => dom/workers/test/threadErrors_worker1.js rename : dom/src/threads/test/threadErrors_worker2.js => dom/workers/test/threadErrors_worker2.js rename : dom/src/threads/test/threadErrors_worker3.js => dom/workers/test/threadErrors_worker3.js rename : dom/src/threads/test/threadErrors_worker4.js => dom/workers/test/threadErrors_worker4.js rename : dom/src/threads/test/threadTimeouts_worker.js => dom/workers/test/threadTimeouts_worker.js rename : dom/src/threads/test/throwingOnerror_worker.js => dom/workers/test/throwingOnerror_worker.js rename : dom/src/threads/test/xhrAbort_worker.js => dom/workers/test/xhrAbort_worker.js rename : dom/src/threads/test/xhr_worker.js => dom/workers/test/xhr_worker.js
2011-07-17 12:09:13 -07:00
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Web Workers.
*
* The Initial Developer of the Original Code is
* The Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ben Turner <bent.mozilla@gmail.com> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "XMLHttpRequestPrivate.h"
#include "nsIDOMEvent.h"
#include "nsIDOMEventListener.h"
#include "nsIDOMProgressEvent.h"
#include "nsIJSContextStack.h"
#include "nsIRunnable.h"
#include "nsIXMLHttpRequest.h"
#include "nsIXPConnect.h"
#include "jstypedarray.h"
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "nsContentUtils.h"
#include "nsJSUtils.h"
#include "nsThreadUtils.h"
#include "nsXMLHttpRequest.h"
#include "Events.h"
#include "EventTarget.h"
#include "Exceptions.h"
#include "RuntimeService.h"
#include "XMLHttpRequest.h"
BEGIN_WORKERS_NAMESPACE
namespace xhr {
Bug 649537 - 'Workers: Make one OS thread and JS runtime per worker, and lose XPConnect'. r=sicking+mrbkap. * * * Bug 649537 - 'Workers: Make one OS thread and JS runtime per worker, and lose XPConnect'. r=sicking+mrbkap. Add workaround for bug 666963. --HG-- rename : dom/src/threads/Makefile.in => dom/workers/Makefile.in rename : dom/src/threads/test/Makefile.in => dom/workers/test/Makefile.in rename : dom/src/threads/test/WorkerTest.jsm => dom/workers/test/WorkerTest.jsm rename : dom/src/threads/test/WorkerTest_badworker.js => dom/workers/test/WorkerTest_badworker.js rename : dom/src/threads/test/WorkerTest_subworker.js => dom/workers/test/WorkerTest_subworker.js rename : dom/src/threads/test/WorkerTest_worker.js => dom/workers/test/WorkerTest_worker.js rename : dom/src/threads/test/atob_worker.js => dom/workers/test/atob_worker.js rename : dom/src/threads/test/chromeWorker_subworker.js => dom/workers/test/chromeWorker_subworker.js rename : dom/src/threads/test/chromeWorker_worker.js => dom/workers/test/chromeWorker_worker.js rename : dom/src/threads/test/closeOnGC_server.sjs => dom/workers/test/closeOnGC_server.sjs rename : dom/src/threads/test/closeOnGC_worker.js => dom/workers/test/closeOnGC_worker.js rename : dom/src/threads/test/close_worker.js => dom/workers/test/close_worker.js rename : dom/src/threads/test/fibonacci_worker.js => dom/workers/test/fibonacci_worker.js rename : dom/src/threads/test/importScripts_worker.js => dom/workers/test/importScripts_worker.js rename : dom/src/threads/test/importScripts_worker_imported1.js => dom/workers/test/importScripts_worker_imported1.js rename : dom/src/threads/test/importScripts_worker_imported2.js => dom/workers/test/importScripts_worker_imported2.js rename : dom/src/threads/test/importScripts_worker_imported3.js => dom/workers/test/importScripts_worker_imported3.js rename : dom/src/threads/test/importScripts_worker_imported4.js => dom/workers/test/importScripts_worker_imported4.js rename : dom/src/threads/test/json_worker.js => dom/workers/test/json_worker.js rename : dom/src/threads/test/location_worker.js => dom/workers/test/location_worker.js rename : dom/src/threads/test/longThread_worker.js => dom/workers/test/longThread_worker.js rename : dom/src/threads/test/navigator_worker.js => dom/workers/test/navigator_worker.js rename : dom/src/threads/test/newError_worker.js => dom/workers/test/newError_worker.js rename : dom/src/threads/test/recursion_worker.js => dom/workers/test/recursion_worker.js rename : dom/src/threads/test/relativeLoad_import.js => dom/workers/test/relativeLoad_import.js rename : dom/src/threads/test/relativeLoad_sub_import.js => dom/workers/test/relativeLoad_sub_import.js rename : dom/src/threads/test/relativeLoad_sub_worker.js => dom/workers/test/relativeLoad_sub_worker.js rename : dom/src/threads/test/relativeLoad_sub_worker2.js => dom/workers/test/relativeLoad_sub_worker2.js rename : dom/src/threads/test/relativeLoad_worker.js => dom/workers/test/relativeLoad_worker.js rename : dom/src/threads/test/relativeLoad_worker2.js => dom/workers/test/relativeLoad_worker2.js rename : dom/src/threads/test/simpleThread_worker.js => dom/workers/test/simpleThread_worker.js rename : dom/src/threads/test/suspend_iframe.html => dom/workers/test/suspend_iframe.html rename : dom/src/threads/test/suspend_worker.js => dom/workers/test/suspend_worker.js rename : dom/src/threads/test/terminate_worker.js => dom/workers/test/terminate_worker.js rename : dom/src/threads/test/testXHR.txt => dom/workers/test/testXHR.txt rename : dom/src/threads/test/test_404.html => dom/workers/test/test_404.html rename : dom/src/threads/test/test_atob.html => dom/workers/test/test_atob.html rename : dom/src/threads/test/test_chromeWorker.html => dom/workers/test/test_chromeWorker.html rename : dom/src/threads/test/test_chromeWorker.xul => dom/workers/test/test_chromeWorker.xul rename : dom/src/threads/test/test_chromeWorkerJSM.xul => dom/workers/test/test_chromeWorkerJSM.xul rename : dom/src/threads/test/test_close.html => dom/workers/test/test_close.html rename : dom/src/threads/test/test_closeOnGC.html => dom/workers/test/test_closeOnGC.html rename : dom/src/threads/test/test_errorPropagation.html => dom/workers/test/test_errorPropagation.html rename : dom/src/threads/test/test_fibonacci.html => dom/workers/test/test_fibonacci.html rename : dom/src/threads/test/test_importScripts.html => dom/workers/test/test_importScripts.html rename : dom/src/threads/test/test_json.html => dom/workers/test/test_json.html rename : dom/src/threads/test/test_location.html => dom/workers/test/test_location.html rename : dom/src/threads/test/test_longThread.html => dom/workers/test/test_longThread.html rename : dom/src/threads/test/test_navigator.html => dom/workers/test/test_navigator.html rename : dom/src/threads/test/test_newError.html => dom/workers/test/test_newError.html rename : dom/src/threads/test/test_recursion.html => dom/workers/test/test_recursion.html rename : dom/src/threads/test/test_relativeLoad.html => dom/workers/test/test_relativeLoad.html rename : dom/src/threads/test/test_simpleThread.html => dom/workers/test/test_simpleThread.html rename : dom/src/threads/test/test_suspend.html => dom/workers/test/test_suspend.html rename : dom/src/threads/test/test_terminate.html => dom/workers/test/test_terminate.html rename : dom/src/threads/test/test_threadErrors.html => dom/workers/test/test_threadErrors.html rename : dom/src/threads/test/test_threadTimeouts.html => dom/workers/test/test_threadTimeouts.html rename : dom/src/threads/test/test_throwingOnerror.html => dom/workers/test/test_throwingOnerror.html rename : dom/src/threads/test/test_xhr.html => dom/workers/test/test_xhr.html rename : dom/src/threads/test/test_xhrAbort.html => dom/workers/test/test_xhrAbort.html rename : dom/src/threads/test/threadErrors_worker1.js => dom/workers/test/threadErrors_worker1.js rename : dom/src/threads/test/threadErrors_worker2.js => dom/workers/test/threadErrors_worker2.js rename : dom/src/threads/test/threadErrors_worker3.js => dom/workers/test/threadErrors_worker3.js rename : dom/src/threads/test/threadErrors_worker4.js => dom/workers/test/threadErrors_worker4.js rename : dom/src/threads/test/threadTimeouts_worker.js => dom/workers/test/threadTimeouts_worker.js rename : dom/src/threads/test/throwingOnerror_worker.js => dom/workers/test/throwingOnerror_worker.js rename : dom/src/threads/test/xhrAbort_worker.js => dom/workers/test/xhrAbort_worker.js rename : dom/src/threads/test/xhr_worker.js => dom/workers/test/xhr_worker.js
2011-07-17 12:09:13 -07:00
class Proxy : public nsIDOMEventListener
{
public:
// Read on multiple threads.
WorkerPrivate* mWorkerPrivate;
XMLHttpRequestPrivate* mXMLHttpRequestPrivate;
// Only touched on the main thread.
nsRefPtr<nsXMLHttpRequest> mXHR;
nsCOMPtr<nsIXMLHttpRequestUpload> mXHRUpload;
PRUint32 mInnerChannelId;
// Only touched on the worker thread.
PRUint32 mOuterChannelId;
PRUint64 mLastLoaded;
PRUint64 mLastTotal;
PRUint64 mLastUploadLoaded;
PRUint64 mLastUploadTotal;
bool mIsSyncXHR;
bool mLastLengthComputable;
bool mLastUploadLengthComputable;
bool mSeenLoadStart;
bool mSeenUploadLoadStart;
// Only touched on the main thread.
nsString mPreviousResponseText;
nsCString mPreviousStatusText;
PRUint32 mSyncQueueKey;
PRUint32 mSyncEventResponseSyncQueueKey;
bool mUploadEventListenersAttached;
bool mMainThreadSeenLoadStart;
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMEVENTLISTENER
Proxy(XMLHttpRequestPrivate* aXHRPrivate)
: mWorkerPrivate(nsnull), mXMLHttpRequestPrivate(aXHRPrivate),
mInnerChannelId(0), mOuterChannelId(0), mLastLoaded(0), mLastTotal(0),
mLastUploadLoaded(0), mLastUploadTotal(0), mIsSyncXHR(false),
mLastLengthComputable(false), mLastUploadLengthComputable(false),
mSeenLoadStart(false), mSeenUploadLoadStart(false),
mSyncQueueKey(PR_UINT32_MAX), mSyncEventResponseSyncQueueKey(PR_UINT32_MAX),
mUploadEventListenersAttached(false), mMainThreadSeenLoadStart(false)
{ }
~Proxy()
{
NS_ASSERTION(!mXHR, "Still have an XHR object attached!");
NS_ASSERTION(!mXHRUpload, "Still have an XHR upload object attached!");
}
bool
Init()
{
AssertIsOnMainThread();
NS_ASSERTION(mWorkerPrivate, "Must have a worker here!");
if (!mXHR) {
mXHR = new nsXMLHttpRequest();
if (NS_FAILED(mXHR->Init(mWorkerPrivate->GetPrincipal(),
mWorkerPrivate->GetScriptContext(),
mWorkerPrivate->GetWindow(),
mWorkerPrivate->GetBaseURI()))) {
mXHR = nsnull;
return false;
}
if (NS_FAILED(mXHR->GetUpload(getter_AddRefs(mXHRUpload)))) {
mXHR = nsnull;
return false;
}
if (!AddRemoveEventListeners(false, true)) {
mXHRUpload = nsnull;
mXHR = nsnull;
return false;
}
}
return true;
}
void
Teardown();
bool
AddRemoveEventListeners(bool aUpload, bool aAdd);
void
Reset()
{
AssertIsOnMainThread();
mPreviousResponseText.Truncate();
mPreviousStatusText.Truncate();
if (mUploadEventListenersAttached) {
AddRemoveEventListeners(true, false);
}
}
PRUint32
GetSyncQueueKey()
{
AssertIsOnMainThread();
return mSyncEventResponseSyncQueueKey == PR_UINT32_MAX ?
mSyncQueueKey :
mSyncEventResponseSyncQueueKey;
}
bool
EventsBypassSyncQueue()
{
AssertIsOnMainThread();
return mSyncQueueKey == PR_UINT32_MAX &&
mSyncEventResponseSyncQueueKey == PR_UINT32_MAX;
}
};
} // namespace xhr
END_WORKERS_NAMESPACE
USING_WORKERS_NAMESPACE
using mozilla::dom::workers::xhr::XMLHttpRequestPrivate;
using mozilla::dom::workers::xhr::Proxy;
using mozilla::dom::workers::exceptions::ThrowDOMExceptionForCode;
Bug 649537 - 'Workers: Make one OS thread and JS runtime per worker, and lose XPConnect'. r=sicking+mrbkap. * * * Bug 649537 - 'Workers: Make one OS thread and JS runtime per worker, and lose XPConnect'. r=sicking+mrbkap. Add workaround for bug 666963. --HG-- rename : dom/src/threads/Makefile.in => dom/workers/Makefile.in rename : dom/src/threads/test/Makefile.in => dom/workers/test/Makefile.in rename : dom/src/threads/test/WorkerTest.jsm => dom/workers/test/WorkerTest.jsm rename : dom/src/threads/test/WorkerTest_badworker.js => dom/workers/test/WorkerTest_badworker.js rename : dom/src/threads/test/WorkerTest_subworker.js => dom/workers/test/WorkerTest_subworker.js rename : dom/src/threads/test/WorkerTest_worker.js => dom/workers/test/WorkerTest_worker.js rename : dom/src/threads/test/atob_worker.js => dom/workers/test/atob_worker.js rename : dom/src/threads/test/chromeWorker_subworker.js => dom/workers/test/chromeWorker_subworker.js rename : dom/src/threads/test/chromeWorker_worker.js => dom/workers/test/chromeWorker_worker.js rename : dom/src/threads/test/closeOnGC_server.sjs => dom/workers/test/closeOnGC_server.sjs rename : dom/src/threads/test/closeOnGC_worker.js => dom/workers/test/closeOnGC_worker.js rename : dom/src/threads/test/close_worker.js => dom/workers/test/close_worker.js rename : dom/src/threads/test/fibonacci_worker.js => dom/workers/test/fibonacci_worker.js rename : dom/src/threads/test/importScripts_worker.js => dom/workers/test/importScripts_worker.js rename : dom/src/threads/test/importScripts_worker_imported1.js => dom/workers/test/importScripts_worker_imported1.js rename : dom/src/threads/test/importScripts_worker_imported2.js => dom/workers/test/importScripts_worker_imported2.js rename : dom/src/threads/test/importScripts_worker_imported3.js => dom/workers/test/importScripts_worker_imported3.js rename : dom/src/threads/test/importScripts_worker_imported4.js => dom/workers/test/importScripts_worker_imported4.js rename : dom/src/threads/test/json_worker.js => dom/workers/test/json_worker.js rename : dom/src/threads/test/location_worker.js => dom/workers/test/location_worker.js rename : dom/src/threads/test/longThread_worker.js => dom/workers/test/longThread_worker.js rename : dom/src/threads/test/navigator_worker.js => dom/workers/test/navigator_worker.js rename : dom/src/threads/test/newError_worker.js => dom/workers/test/newError_worker.js rename : dom/src/threads/test/recursion_worker.js => dom/workers/test/recursion_worker.js rename : dom/src/threads/test/relativeLoad_import.js => dom/workers/test/relativeLoad_import.js rename : dom/src/threads/test/relativeLoad_sub_import.js => dom/workers/test/relativeLoad_sub_import.js rename : dom/src/threads/test/relativeLoad_sub_worker.js => dom/workers/test/relativeLoad_sub_worker.js rename : dom/src/threads/test/relativeLoad_sub_worker2.js => dom/workers/test/relativeLoad_sub_worker2.js rename : dom/src/threads/test/relativeLoad_worker.js => dom/workers/test/relativeLoad_worker.js rename : dom/src/threads/test/relativeLoad_worker2.js => dom/workers/test/relativeLoad_worker2.js rename : dom/src/threads/test/simpleThread_worker.js => dom/workers/test/simpleThread_worker.js rename : dom/src/threads/test/suspend_iframe.html => dom/workers/test/suspend_iframe.html rename : dom/src/threads/test/suspend_worker.js => dom/workers/test/suspend_worker.js rename : dom/src/threads/test/terminate_worker.js => dom/workers/test/terminate_worker.js rename : dom/src/threads/test/testXHR.txt => dom/workers/test/testXHR.txt rename : dom/src/threads/test/test_404.html => dom/workers/test/test_404.html rename : dom/src/threads/test/test_atob.html => dom/workers/test/test_atob.html rename : dom/src/threads/test/test_chromeWorker.html => dom/workers/test/test_chromeWorker.html rename : dom/src/threads/test/test_chromeWorker.xul => dom/workers/test/test_chromeWorker.xul rename : dom/src/threads/test/test_chromeWorkerJSM.xul => dom/workers/test/test_chromeWorkerJSM.xul rename : dom/src/threads/test/test_close.html => dom/workers/test/test_close.html rename : dom/src/threads/test/test_closeOnGC.html => dom/workers/test/test_closeOnGC.html rename : dom/src/threads/test/test_errorPropagation.html => dom/workers/test/test_errorPropagation.html rename : dom/src/threads/test/test_fibonacci.html => dom/workers/test/test_fibonacci.html rename : dom/src/threads/test/test_importScripts.html => dom/workers/test/test_importScripts.html rename : dom/src/threads/test/test_json.html => dom/workers/test/test_json.html rename : dom/src/threads/test/test_location.html => dom/workers/test/test_location.html rename : dom/src/threads/test/test_longThread.html => dom/workers/test/test_longThread.html rename : dom/src/threads/test/test_navigator.html => dom/workers/test/test_navigator.html rename : dom/src/threads/test/test_newError.html => dom/workers/test/test_newError.html rename : dom/src/threads/test/test_recursion.html => dom/workers/test/test_recursion.html rename : dom/src/threads/test/test_relativeLoad.html => dom/workers/test/test_relativeLoad.html rename : dom/src/threads/test/test_simpleThread.html => dom/workers/test/test_simpleThread.html rename : dom/src/threads/test/test_suspend.html => dom/workers/test/test_suspend.html rename : dom/src/threads/test/test_terminate.html => dom/workers/test/test_terminate.html rename : dom/src/threads/test/test_threadErrors.html => dom/workers/test/test_threadErrors.html rename : dom/src/threads/test/test_threadTimeouts.html => dom/workers/test/test_threadTimeouts.html rename : dom/src/threads/test/test_throwingOnerror.html => dom/workers/test/test_throwingOnerror.html rename : dom/src/threads/test/test_xhr.html => dom/workers/test/test_xhr.html rename : dom/src/threads/test/test_xhrAbort.html => dom/workers/test/test_xhrAbort.html rename : dom/src/threads/test/threadErrors_worker1.js => dom/workers/test/threadErrors_worker1.js rename : dom/src/threads/test/threadErrors_worker2.js => dom/workers/test/threadErrors_worker2.js rename : dom/src/threads/test/threadErrors_worker3.js => dom/workers/test/threadErrors_worker3.js rename : dom/src/threads/test/threadErrors_worker4.js => dom/workers/test/threadErrors_worker4.js rename : dom/src/threads/test/threadTimeouts_worker.js => dom/workers/test/threadTimeouts_worker.js rename : dom/src/threads/test/throwingOnerror_worker.js => dom/workers/test/throwingOnerror_worker.js rename : dom/src/threads/test/xhrAbort_worker.js => dom/workers/test/xhrAbort_worker.js rename : dom/src/threads/test/xhr_worker.js => dom/workers/test/xhr_worker.js
2011-07-17 12:09:13 -07:00
namespace {
inline intN
GetDOMExceptionCodeFromResult(nsresult aResult)
{
if (NS_SUCCEEDED(aResult)) {
return 0;
}
if (NS_ERROR_GET_MODULE(aResult) == NS_ERROR_MODULE_DOM) {
return NS_ERROR_GET_CODE(aResult);
}
NS_WARNING("Update main thread implementation for a DOM error code here!");
return INVALID_STATE_ERR;
}
enum
{
STRING_abort = 0,
STRING_error,
STRING_load,
STRING_loadstart,
STRING_progress,
STRING_readystatechange,
STRING_loadend,
STRING_COUNT,
STRING_LAST_XHR = STRING_loadend,
STRING_LAST_EVENTTARGET = STRING_progress
};
JS_STATIC_ASSERT(STRING_LAST_XHR >= STRING_LAST_EVENTTARGET);
JS_STATIC_ASSERT(STRING_LAST_XHR == STRING_COUNT - 1);
const char* const sEventStrings[] = {
// nsIXMLHttpRequestEventTarget event types, supported by both XHR and Upload.
"abort",
"error",
"load",
"loadstart",
"progress",
// nsIXMLHttpRequest event types, supported only by XHR.
"readystatechange",
"loadend",
};
JS_STATIC_ASSERT(JS_ARRAY_LENGTH(sEventStrings) == STRING_COUNT);
class MainThreadSyncRunnable : public WorkerSyncRunnable
{
public:
MainThreadSyncRunnable(WorkerPrivate* aWorkerPrivate, PRUint32 aSyncQueueKey,
bool aBypassSyncEventQueue)
: WorkerSyncRunnable(aWorkerPrivate, aSyncQueueKey, aBypassSyncEventQueue)
{
AssertIsOnMainThread();
}
bool
PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
{
AssertIsOnMainThread();
return true;
}
void
PostDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
bool aDispatchResult)
{
AssertIsOnMainThread();
}
};
class MainThreadProxyRunnable : public MainThreadSyncRunnable
{
protected:
nsRefPtr<Proxy> mProxy;
public:
MainThreadProxyRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy)
: MainThreadSyncRunnable(aWorkerPrivate, aProxy->GetSyncQueueKey(),
aProxy->EventsBypassSyncQueue()),
mProxy(aProxy)
{ }
};
class TeardownRunnable : public nsRunnable
{
Proxy* mProxy;
public:
TeardownRunnable(nsRefPtr<Proxy>& aProxy)
{
aProxy.forget(&mProxy);
NS_ASSERTION(mProxy, "Null proxy!");
}
NS_IMETHOD Run()
{
AssertIsOnMainThread();
mProxy->Teardown();
NS_RELEASE(mProxy);
return NS_OK;
}
};
class LoadStartDetectionRunnable : public nsIRunnable,
public nsIDOMEventListener
{
WorkerPrivate* mWorkerPrivate;
nsRefPtr<Proxy> mProxy;
nsRefPtr<nsXMLHttpRequest> mXHR;
XMLHttpRequestPrivate* mXMLHttpRequestPrivate;
nsString mEventType;
bool mReceivedLoadStart;
class ProxyCompleteRunnable : public MainThreadProxyRunnable
{
XMLHttpRequestPrivate* mXMLHttpRequestPrivate;
public:
ProxyCompleteRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
XMLHttpRequestPrivate* aXHRPrivate)
: MainThreadProxyRunnable(aWorkerPrivate, aProxy),
mXMLHttpRequestPrivate(aXHRPrivate)
{ }
bool
PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
{
AssertIsOnMainThread();
return true;
}
void
PostDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
bool aDispatchResult)
{
AssertIsOnMainThread();
}
bool
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
{
if (mSyncQueueKey != PR_UINT32_MAX) {
aWorkerPrivate->StopSyncLoop(mSyncQueueKey, true);
}
mXMLHttpRequestPrivate->UnrootJSObject(aCx);
aWorkerPrivate->RemoveFeature(aCx, mXMLHttpRequestPrivate);
return true;
}
};
public:
NS_DECL_ISUPPORTS
LoadStartDetectionRunnable(Proxy* aProxy, XMLHttpRequestPrivate* aXHRPrivate)
: mWorkerPrivate(aProxy->mWorkerPrivate), mProxy(aProxy), mXHR(aProxy->mXHR),
mXMLHttpRequestPrivate(aXHRPrivate), mReceivedLoadStart(false)
{
AssertIsOnMainThread();
mEventType.AssignWithConversion(sEventStrings[STRING_loadstart]);
}
~LoadStartDetectionRunnable()
{
AssertIsOnMainThread();
}
bool
RegisterAndDispatch()
{
AssertIsOnMainThread();
if (NS_FAILED(mXHR->AddEventListener(mEventType, this, false, false, 2))) {
NS_WARNING("Failed to add event listener!");
return false;
}
return NS_SUCCEEDED(NS_DispatchToCurrentThread(this));
}
NS_IMETHOD
Run()
{
AssertIsOnMainThread();
if (NS_FAILED(mXHR->RemoveEventListener(mEventType, this, false))) {
NS_WARNING("Failed to remove event listener!");
}
if (!mReceivedLoadStart) {
mProxy->Reset();
if (mProxy->mWorkerPrivate) {
nsRefPtr<ProxyCompleteRunnable> runnable =
new ProxyCompleteRunnable(mWorkerPrivate, mProxy,
mXMLHttpRequestPrivate);
if (!runnable->Dispatch(nsnull)) {
NS_WARNING("Failed to dispatch ProxyCompleteRunnable!");
}
mProxy->mWorkerPrivate = nsnull;
}
}
mProxy = nsnull;
mXHR = nsnull;
mXMLHttpRequestPrivate = nsnull;
return NS_OK;
}
NS_IMETHOD
HandleEvent(nsIDOMEvent* aEvent)
{
AssertIsOnMainThread();
#ifdef DEBUG
{
nsString type;
if (NS_SUCCEEDED(aEvent->GetType(type))) {
NS_ASSERTION(type == mEventType, "Unexpected event type!");
}
else {
NS_WARNING("Failed to get event type!");
}
}
#endif
mReceivedLoadStart = true;
return NS_OK;
}
};
NS_IMPL_ISUPPORTS2(LoadStartDetectionRunnable, nsIRunnable, nsIDOMEventListener)
class EventRunnable : public MainThreadProxyRunnable
{
nsString mType;
nsString mResponseText;
nsCString mStatusText;
PRUint64 mLoaded;
PRUint64 mTotal;
PRUint32 mChannelId;
PRUint32 mStatus;
PRUint16 mReadyState;
bool mUploadEvent;
bool mProgressEvent;
bool mLengthComputable;
bool mResponseTextException;
bool mStatusException;
bool mStatusTextException;
bool mReadyStateException;
public:
EventRunnable(Proxy* aProxy, bool aUploadEvent, const nsString& aType,
bool aLengthComputable, PRUint64 aLoaded, PRUint64 aTotal)
: MainThreadProxyRunnable(aProxy->mWorkerPrivate, aProxy), mType(aType),
mLoaded(aLoaded), mTotal(aTotal), mChannelId(aProxy->mInnerChannelId),
mStatus(0), mReadyState(0), mUploadEvent(aUploadEvent),
mProgressEvent(true), mLengthComputable(aLengthComputable),
mResponseTextException(false), mStatusException(false),
mStatusTextException(false), mReadyStateException(false)
{ }
EventRunnable(Proxy* aProxy, bool aUploadEvent, const nsString& aType)
: MainThreadProxyRunnable(aProxy->mWorkerPrivate, aProxy), mType(aType),
mLoaded(0), mTotal(0), mChannelId(aProxy->mInnerChannelId), mStatus(0),
mReadyState(0), mUploadEvent(aUploadEvent), mProgressEvent(false),
mLengthComputable(0), mResponseTextException(false),
mStatusException(false), mStatusTextException(false),
mReadyStateException(false)
{ }
bool
PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
{
nsRefPtr<nsXMLHttpRequest>& xhr = mProxy->mXHR;
NS_ASSERTION(xhr, "Must have an XHR here!");
if (NS_SUCCEEDED(xhr->GetResponseText(mResponseText))) {
if (mResponseText == mProxy->mPreviousResponseText) {
mResponseText.SetIsVoid(true);
}
else {
mProxy->mPreviousResponseText = mResponseText;
}
mResponseTextException = false;
}
else {
mResponseTextException = true;
}
mStatusException = NS_FAILED(xhr->GetStatus(&mStatus));
if (NS_SUCCEEDED(xhr->GetStatusText(mStatusText))) {
if (mStatusText == mProxy->mPreviousStatusText) {
mStatusText.SetIsVoid(true);
}
else {
mProxy->mPreviousStatusText = mStatusText;
}
mStatusTextException = false;
}
else {
mStatusTextException = true;
}
mReadyStateException = NS_FAILED(xhr->GetReadyState(&mReadyState));
return true;
}
bool
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
{
if (mChannelId != mProxy->mOuterChannelId) {
// Threads raced, this event is now obsolete.
return true;
}
if (!mProxy->mXMLHttpRequestPrivate) {
// Object was finalized, bail.
return true;
}
if (mType.EqualsASCII(sEventStrings[STRING_loadstart])) {
if (mUploadEvent) {
mProxy->mSeenUploadLoadStart = true;
}
else {
mProxy->mSeenLoadStart = true;
}
}
else if (mType.EqualsASCII(sEventStrings[STRING_loadend])) {
if (mUploadEvent) {
mProxy->mSeenUploadLoadStart = false;
}
else {
mProxy->mSeenLoadStart = false;
}
}
if (mProgressEvent) {
// Cache these for premature abort events.
if (mUploadEvent) {
mProxy->mLastUploadLengthComputable = mLengthComputable;
mProxy->mLastUploadLoaded = mLoaded;
mProxy->mLastUploadTotal = mTotal;
}
else {
mProxy->mLastLengthComputable = mLengthComputable;
mProxy->mLastLoaded = mLoaded;
mProxy->mLastTotal = mTotal;
}
}
JSObject* target = mUploadEvent ?
mProxy->mXMLHttpRequestPrivate->GetUploadJSObject() :
mProxy->mXMLHttpRequestPrivate->GetJSObject();
if (!target) {
NS_ASSERTION(mUploadEvent, "How else is this possible?!");
return true;
}
xhr::StateData state;
state.mResponseTextException = mResponseTextException;
if (mResponseTextException || mResponseText.IsVoid()) {
state.mResponseText = JSVAL_VOID;
}
else if (mResponseText.IsEmpty()) {
state.mResponseText = JS_GetEmptyStringValue(aCx);
}
else {
JSString* responseText = JS_NewUCStringCopyN(aCx, mResponseText.get(),
mResponseText.Length());
if (!responseText) {
return false;
}
mResponseText.Truncate();
state.mResponseText = STRING_TO_JSVAL(responseText);
}
state.mStatusException = mStatusException;
state.mStatus = mStatusException ? JSVAL_VOID : INT_TO_JSVAL(mStatus);
state.mStatusTextException = mStatusTextException;
if (mStatusTextException || mStatusText.IsVoid()) {
state.mStatusText = JSVAL_VOID;
}
else if (mStatusText.IsEmpty()) {
state.mStatusText = JS_GetEmptyStringValue(aCx);
}
else {
JSString* statusText = JS_NewStringCopyN(aCx, mStatusText.get(),
mStatusText.Length());
if (!statusText) {
return false;
}
mStatusText.Truncate();
state.mStatusText = STRING_TO_JSVAL(statusText);
}
state.mReadyStateException = mReadyStateException;
state.mReadyState = mReadyStateException ?
JSVAL_VOID :
INT_TO_JSVAL(mReadyState);
if (!xhr::UpdateXHRState(aCx, target, mUploadEvent, state)) {
Bug 649537 - 'Workers: Make one OS thread and JS runtime per worker, and lose XPConnect'. r=sicking+mrbkap. * * * Bug 649537 - 'Workers: Make one OS thread and JS runtime per worker, and lose XPConnect'. r=sicking+mrbkap. Add workaround for bug 666963. --HG-- rename : dom/src/threads/Makefile.in => dom/workers/Makefile.in rename : dom/src/threads/test/Makefile.in => dom/workers/test/Makefile.in rename : dom/src/threads/test/WorkerTest.jsm => dom/workers/test/WorkerTest.jsm rename : dom/src/threads/test/WorkerTest_badworker.js => dom/workers/test/WorkerTest_badworker.js rename : dom/src/threads/test/WorkerTest_subworker.js => dom/workers/test/WorkerTest_subworker.js rename : dom/src/threads/test/WorkerTest_worker.js => dom/workers/test/WorkerTest_worker.js rename : dom/src/threads/test/atob_worker.js => dom/workers/test/atob_worker.js rename : dom/src/threads/test/chromeWorker_subworker.js => dom/workers/test/chromeWorker_subworker.js rename : dom/src/threads/test/chromeWorker_worker.js => dom/workers/test/chromeWorker_worker.js rename : dom/src/threads/test/closeOnGC_server.sjs => dom/workers/test/closeOnGC_server.sjs rename : dom/src/threads/test/closeOnGC_worker.js => dom/workers/test/closeOnGC_worker.js rename : dom/src/threads/test/close_worker.js => dom/workers/test/close_worker.js rename : dom/src/threads/test/fibonacci_worker.js => dom/workers/test/fibonacci_worker.js rename : dom/src/threads/test/importScripts_worker.js => dom/workers/test/importScripts_worker.js rename : dom/src/threads/test/importScripts_worker_imported1.js => dom/workers/test/importScripts_worker_imported1.js rename : dom/src/threads/test/importScripts_worker_imported2.js => dom/workers/test/importScripts_worker_imported2.js rename : dom/src/threads/test/importScripts_worker_imported3.js => dom/workers/test/importScripts_worker_imported3.js rename : dom/src/threads/test/importScripts_worker_imported4.js => dom/workers/test/importScripts_worker_imported4.js rename : dom/src/threads/test/json_worker.js => dom/workers/test/json_worker.js rename : dom/src/threads/test/location_worker.js => dom/workers/test/location_worker.js rename : dom/src/threads/test/longThread_worker.js => dom/workers/test/longThread_worker.js rename : dom/src/threads/test/navigator_worker.js => dom/workers/test/navigator_worker.js rename : dom/src/threads/test/newError_worker.js => dom/workers/test/newError_worker.js rename : dom/src/threads/test/recursion_worker.js => dom/workers/test/recursion_worker.js rename : dom/src/threads/test/relativeLoad_import.js => dom/workers/test/relativeLoad_import.js rename : dom/src/threads/test/relativeLoad_sub_import.js => dom/workers/test/relativeLoad_sub_import.js rename : dom/src/threads/test/relativeLoad_sub_worker.js => dom/workers/test/relativeLoad_sub_worker.js rename : dom/src/threads/test/relativeLoad_sub_worker2.js => dom/workers/test/relativeLoad_sub_worker2.js rename : dom/src/threads/test/relativeLoad_worker.js => dom/workers/test/relativeLoad_worker.js rename : dom/src/threads/test/relativeLoad_worker2.js => dom/workers/test/relativeLoad_worker2.js rename : dom/src/threads/test/simpleThread_worker.js => dom/workers/test/simpleThread_worker.js rename : dom/src/threads/test/suspend_iframe.html => dom/workers/test/suspend_iframe.html rename : dom/src/threads/test/suspend_worker.js => dom/workers/test/suspend_worker.js rename : dom/src/threads/test/terminate_worker.js => dom/workers/test/terminate_worker.js rename : dom/src/threads/test/testXHR.txt => dom/workers/test/testXHR.txt rename : dom/src/threads/test/test_404.html => dom/workers/test/test_404.html rename : dom/src/threads/test/test_atob.html => dom/workers/test/test_atob.html rename : dom/src/threads/test/test_chromeWorker.html => dom/workers/test/test_chromeWorker.html rename : dom/src/threads/test/test_chromeWorker.xul => dom/workers/test/test_chromeWorker.xul rename : dom/src/threads/test/test_chromeWorkerJSM.xul => dom/workers/test/test_chromeWorkerJSM.xul rename : dom/src/threads/test/test_close.html => dom/workers/test/test_close.html rename : dom/src/threads/test/test_closeOnGC.html => dom/workers/test/test_closeOnGC.html rename : dom/src/threads/test/test_errorPropagation.html => dom/workers/test/test_errorPropagation.html rename : dom/src/threads/test/test_fibonacci.html => dom/workers/test/test_fibonacci.html rename : dom/src/threads/test/test_importScripts.html => dom/workers/test/test_importScripts.html rename : dom/src/threads/test/test_json.html => dom/workers/test/test_json.html rename : dom/src/threads/test/test_location.html => dom/workers/test/test_location.html rename : dom/src/threads/test/test_longThread.html => dom/workers/test/test_longThread.html rename : dom/src/threads/test/test_navigator.html => dom/workers/test/test_navigator.html rename : dom/src/threads/test/test_newError.html => dom/workers/test/test_newError.html rename : dom/src/threads/test/test_recursion.html => dom/workers/test/test_recursion.html rename : dom/src/threads/test/test_relativeLoad.html => dom/workers/test/test_relativeLoad.html rename : dom/src/threads/test/test_simpleThread.html => dom/workers/test/test_simpleThread.html rename : dom/src/threads/test/test_suspend.html => dom/workers/test/test_suspend.html rename : dom/src/threads/test/test_terminate.html => dom/workers/test/test_terminate.html rename : dom/src/threads/test/test_threadErrors.html => dom/workers/test/test_threadErrors.html rename : dom/src/threads/test/test_threadTimeouts.html => dom/workers/test/test_threadTimeouts.html rename : dom/src/threads/test/test_throwingOnerror.html => dom/workers/test/test_throwingOnerror.html rename : dom/src/threads/test/test_xhr.html => dom/workers/test/test_xhr.html rename : dom/src/threads/test/test_xhrAbort.html => dom/workers/test/test_xhrAbort.html rename : dom/src/threads/test/threadErrors_worker1.js => dom/workers/test/threadErrors_worker1.js rename : dom/src/threads/test/threadErrors_worker2.js => dom/workers/test/threadErrors_worker2.js rename : dom/src/threads/test/threadErrors_worker3.js => dom/workers/test/threadErrors_worker3.js rename : dom/src/threads/test/threadErrors_worker4.js => dom/workers/test/threadErrors_worker4.js rename : dom/src/threads/test/threadTimeouts_worker.js => dom/workers/test/threadTimeouts_worker.js rename : dom/src/threads/test/throwingOnerror_worker.js => dom/workers/test/throwingOnerror_worker.js rename : dom/src/threads/test/xhrAbort_worker.js => dom/workers/test/xhrAbort_worker.js rename : dom/src/threads/test/xhr_worker.js => dom/workers/test/xhr_worker.js
2011-07-17 12:09:13 -07:00
return false;
}
JSString* type = JS_NewUCStringCopyN(aCx, mType.get(), mType.Length());
if (!type) {
return false;
}
JSObject* event = mProgressEvent ?
events::CreateProgressEvent(aCx, type, mLengthComputable,
mLoaded, mTotal) :
events::CreateGenericEvent(aCx, type, false, false,
false);
if (!event) {
return false;
}
bool dummy;
if (!events::DispatchEventToTarget(aCx, target, event, &dummy)) {
JS_ReportPendingException(aCx);
}
return true;
}
};
class WorkerThreadProxySyncRunnable : public nsRunnable
{
protected:
WorkerPrivate* mWorkerPrivate;
nsRefPtr<Proxy> mProxy;
PRUint32 mSyncQueueKey;
private:
class ResponseRunnable : public MainThreadProxyRunnable
{
PRUint32 mSyncQueueKey;
intN mErrorCode;
public:
ResponseRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
PRUint32 aSyncQueueKey, intN aErrorCode)
: MainThreadProxyRunnable(aWorkerPrivate, aProxy),
mSyncQueueKey(aSyncQueueKey), mErrorCode(aErrorCode)
{
NS_ASSERTION(aProxy, "Don't hand me a null proxy!");
}
bool
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
{
if (mErrorCode) {
ThrowDOMExceptionForCode(aCx, mErrorCode);
aWorkerPrivate->StopSyncLoop(mSyncQueueKey, false);
}
else {
aWorkerPrivate->StopSyncLoop(mSyncQueueKey, true);
}
return true;
}
};
public:
WorkerThreadProxySyncRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy)
: mWorkerPrivate(aWorkerPrivate), mProxy(aProxy), mSyncQueueKey(0)
{
mWorkerPrivate->AssertIsOnWorkerThread();
NS_ASSERTION(aProxy, "Don't hand me a null proxy!");
MOZ_COUNT_CTOR(mozilla::dom::workers::xhr::WorkerThreadProxySyncRunnable);
}
~WorkerThreadProxySyncRunnable()
{
MOZ_COUNT_DTOR(mozilla::dom::workers::xhr::WorkerThreadProxySyncRunnable);
}
bool
Dispatch(JSContext* aCx)
{
mWorkerPrivate->AssertIsOnWorkerThread();
mSyncQueueKey = mWorkerPrivate->CreateNewSyncLoop();
if (NS_FAILED(NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL))) {
JS_ReportError(aCx, "Failed to initialize XHR!");
return false;
}
if (!mWorkerPrivate->RunSyncLoop(aCx, mSyncQueueKey)) {
return false;
}
return true;
}
virtual intN
MainThreadRun() = 0;
NS_IMETHOD
Run()
{
AssertIsOnMainThread();
PRUint32 oldSyncQueueKey = mProxy->mSyncEventResponseSyncQueueKey;
mProxy->mSyncEventResponseSyncQueueKey = mSyncQueueKey;
intN rv = MainThreadRun();
nsRefPtr<ResponseRunnable> response =
new ResponseRunnable(mWorkerPrivate, mProxy, mSyncQueueKey, rv);
if (!response->Dispatch(nsnull)) {
NS_WARNING("Failed to dispatch response!");
}
mProxy->mSyncEventResponseSyncQueueKey = oldSyncQueueKey;
return NS_OK;
}
};
class SetMultipartRunnable : public WorkerThreadProxySyncRunnable
{
bool mValue;
public:
SetMultipartRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
bool aValue)
: WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mValue(aValue)
{ }
intN
MainThreadRun()
{
return GetDOMExceptionCodeFromResult(mProxy->mXHR->SetMultipart(mValue));
}
};
class SetBackgroundRequestRunnable : public WorkerThreadProxySyncRunnable
{
bool mValue;
public:
SetBackgroundRequestRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
bool aValue)
: WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mValue(aValue)
{ }
intN
MainThreadRun()
{
nsresult rv = mProxy->mXHR->SetMozBackgroundRequest(mValue);
return GetDOMExceptionCodeFromResult(rv);
}
};
class SetWithCredentialsRunnable : public WorkerThreadProxySyncRunnable
{
bool mValue;
public:
SetWithCredentialsRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
bool aValue)
: WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mValue(aValue)
{ }
intN
MainThreadRun()
{
nsresult rv = mProxy->mXHR->SetWithCredentials(mValue);
return GetDOMExceptionCodeFromResult(rv);
}
};
class AbortRunnable : public WorkerThreadProxySyncRunnable
{
public:
AbortRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy)
: WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy)
{ }
intN
MainThreadRun()
{
mProxy->mInnerChannelId++;
WorkerPrivate* oldWorker = mProxy->mWorkerPrivate;
mProxy->mWorkerPrivate = mWorkerPrivate;
nsresult rv = mProxy->mXHR->Abort();
mProxy->mWorkerPrivate = oldWorker;
mProxy->Reset();
return GetDOMExceptionCodeFromResult(rv);
}
};
class GetAllResponseHeadersRunnable : public WorkerThreadProxySyncRunnable
{
nsCString& mResponseHeaders;
public:
GetAllResponseHeadersRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
nsCString& aResponseHeaders)
: WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy),
mResponseHeaders(aResponseHeaders)
{ }
intN
MainThreadRun()
{
nsresult rv =
mProxy->mXHR->GetAllResponseHeaders(getter_Copies(mResponseHeaders));
return GetDOMExceptionCodeFromResult(rv);
}
};
class GetResponseHeaderRunnable : public WorkerThreadProxySyncRunnable
{
const nsCString mHeader;
nsCString& mValue;
public:
GetResponseHeaderRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
const nsCString& aHeader, nsCString& aValue)
: WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mHeader(aHeader),
mValue(aValue)
{ }
intN
MainThreadRun()
{
nsresult rv = mProxy->mXHR->GetResponseHeader(mHeader, mValue);
return GetDOMExceptionCodeFromResult(rv);
}
};
class OpenRunnable : public WorkerThreadProxySyncRunnable
{
nsCString mMethod;
nsCString mURL;
nsString mUser;
nsString mPassword;
bool mMultipart;
bool mBackgroundRequest;
bool mWithCredentials;
public:
OpenRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
const nsCString& aMethod, const nsCString& aURL,
const nsString& aUser, const nsString& aPassword,
bool aMultipart, bool aBackgroundRequest, bool aWithCredentials)
: WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mMethod(aMethod),
mURL(aURL), mUser(aUser), mPassword(aPassword), mMultipart(aMultipart),
mBackgroundRequest(aBackgroundRequest), mWithCredentials(aWithCredentials)
{ }
intN
MainThreadRun()
{
WorkerPrivate* oldWorker = mProxy->mWorkerPrivate;
mProxy->mWorkerPrivate = mWorkerPrivate;
intN retval = MainThreadRunInternal();
mProxy->mWorkerPrivate = oldWorker;
return retval;
}
intN
MainThreadRunInternal()
{
if (!mProxy->Init()) {
return INVALID_STATE_ERR;
}
nsresult rv;
if (mMultipart) {
rv = mProxy->mXHR->SetMultipart(mMultipart);
if (NS_FAILED(rv)) {
return GetDOMExceptionCodeFromResult(rv);
}
}
if (mBackgroundRequest) {
rv = mProxy->mXHR->SetMozBackgroundRequest(mBackgroundRequest);
if (NS_FAILED(rv)) {
return GetDOMExceptionCodeFromResult(rv);
}
}
if (mWithCredentials) {
rv = mProxy->mXHR->SetWithCredentials(mWithCredentials);
if (NS_FAILED(rv)) {
return GetDOMExceptionCodeFromResult(rv);
}
}
mProxy->mInnerChannelId++;
mProxy->mPreviousResponseText.Truncate();
mProxy->mPreviousStatusText.Truncate();
rv = mProxy->mXHR->Open(mMethod, mURL, true, mUser, mPassword, 1);
return GetDOMExceptionCodeFromResult(rv);
}
};
class SendRunnable : public WorkerThreadProxySyncRunnable
{
JSAutoStructuredCloneBuffer mBody;
PRUint32 mSyncQueueKey;
bool mHasUploadListeners;
public:
SendRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
JSAutoStructuredCloneBuffer& aBody, PRUint32 aSyncQueueKey,
bool aHasUploadListeners)
: WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy),
mSyncQueueKey(aSyncQueueKey), mHasUploadListeners(aHasUploadListeners)
{
mBody.swap(aBody);
}
intN
MainThreadRun()
{
NS_ASSERTION(!mProxy->mWorkerPrivate, "Should be null!");
mProxy->mWorkerPrivate = mWorkerPrivate;
NS_ASSERTION(mProxy->mSyncQueueKey == PR_UINT32_MAX, "Should be unset!");
mProxy->mSyncQueueKey = mSyncQueueKey;
nsCOMPtr<nsIVariant> variant;
if (mBody.data()) {
nsIXPConnect* xpc = nsContentUtils::XPConnect();
NS_ASSERTION(xpc, "This should never be null!");
RuntimeService::AutoSafeJSContext cx;
intN error = 0;
jsval body;
if (mBody.read(cx, &body)) {
Bug 649537 - 'Workers: Make one OS thread and JS runtime per worker, and lose XPConnect'. r=sicking+mrbkap. * * * Bug 649537 - 'Workers: Make one OS thread and JS runtime per worker, and lose XPConnect'. r=sicking+mrbkap. Add workaround for bug 666963. --HG-- rename : dom/src/threads/Makefile.in => dom/workers/Makefile.in rename : dom/src/threads/test/Makefile.in => dom/workers/test/Makefile.in rename : dom/src/threads/test/WorkerTest.jsm => dom/workers/test/WorkerTest.jsm rename : dom/src/threads/test/WorkerTest_badworker.js => dom/workers/test/WorkerTest_badworker.js rename : dom/src/threads/test/WorkerTest_subworker.js => dom/workers/test/WorkerTest_subworker.js rename : dom/src/threads/test/WorkerTest_worker.js => dom/workers/test/WorkerTest_worker.js rename : dom/src/threads/test/atob_worker.js => dom/workers/test/atob_worker.js rename : dom/src/threads/test/chromeWorker_subworker.js => dom/workers/test/chromeWorker_subworker.js rename : dom/src/threads/test/chromeWorker_worker.js => dom/workers/test/chromeWorker_worker.js rename : dom/src/threads/test/closeOnGC_server.sjs => dom/workers/test/closeOnGC_server.sjs rename : dom/src/threads/test/closeOnGC_worker.js => dom/workers/test/closeOnGC_worker.js rename : dom/src/threads/test/close_worker.js => dom/workers/test/close_worker.js rename : dom/src/threads/test/fibonacci_worker.js => dom/workers/test/fibonacci_worker.js rename : dom/src/threads/test/importScripts_worker.js => dom/workers/test/importScripts_worker.js rename : dom/src/threads/test/importScripts_worker_imported1.js => dom/workers/test/importScripts_worker_imported1.js rename : dom/src/threads/test/importScripts_worker_imported2.js => dom/workers/test/importScripts_worker_imported2.js rename : dom/src/threads/test/importScripts_worker_imported3.js => dom/workers/test/importScripts_worker_imported3.js rename : dom/src/threads/test/importScripts_worker_imported4.js => dom/workers/test/importScripts_worker_imported4.js rename : dom/src/threads/test/json_worker.js => dom/workers/test/json_worker.js rename : dom/src/threads/test/location_worker.js => dom/workers/test/location_worker.js rename : dom/src/threads/test/longThread_worker.js => dom/workers/test/longThread_worker.js rename : dom/src/threads/test/navigator_worker.js => dom/workers/test/navigator_worker.js rename : dom/src/threads/test/newError_worker.js => dom/workers/test/newError_worker.js rename : dom/src/threads/test/recursion_worker.js => dom/workers/test/recursion_worker.js rename : dom/src/threads/test/relativeLoad_import.js => dom/workers/test/relativeLoad_import.js rename : dom/src/threads/test/relativeLoad_sub_import.js => dom/workers/test/relativeLoad_sub_import.js rename : dom/src/threads/test/relativeLoad_sub_worker.js => dom/workers/test/relativeLoad_sub_worker.js rename : dom/src/threads/test/relativeLoad_sub_worker2.js => dom/workers/test/relativeLoad_sub_worker2.js rename : dom/src/threads/test/relativeLoad_worker.js => dom/workers/test/relativeLoad_worker.js rename : dom/src/threads/test/relativeLoad_worker2.js => dom/workers/test/relativeLoad_worker2.js rename : dom/src/threads/test/simpleThread_worker.js => dom/workers/test/simpleThread_worker.js rename : dom/src/threads/test/suspend_iframe.html => dom/workers/test/suspend_iframe.html rename : dom/src/threads/test/suspend_worker.js => dom/workers/test/suspend_worker.js rename : dom/src/threads/test/terminate_worker.js => dom/workers/test/terminate_worker.js rename : dom/src/threads/test/testXHR.txt => dom/workers/test/testXHR.txt rename : dom/src/threads/test/test_404.html => dom/workers/test/test_404.html rename : dom/src/threads/test/test_atob.html => dom/workers/test/test_atob.html rename : dom/src/threads/test/test_chromeWorker.html => dom/workers/test/test_chromeWorker.html rename : dom/src/threads/test/test_chromeWorker.xul => dom/workers/test/test_chromeWorker.xul rename : dom/src/threads/test/test_chromeWorkerJSM.xul => dom/workers/test/test_chromeWorkerJSM.xul rename : dom/src/threads/test/test_close.html => dom/workers/test/test_close.html rename : dom/src/threads/test/test_closeOnGC.html => dom/workers/test/test_closeOnGC.html rename : dom/src/threads/test/test_errorPropagation.html => dom/workers/test/test_errorPropagation.html rename : dom/src/threads/test/test_fibonacci.html => dom/workers/test/test_fibonacci.html rename : dom/src/threads/test/test_importScripts.html => dom/workers/test/test_importScripts.html rename : dom/src/threads/test/test_json.html => dom/workers/test/test_json.html rename : dom/src/threads/test/test_location.html => dom/workers/test/test_location.html rename : dom/src/threads/test/test_longThread.html => dom/workers/test/test_longThread.html rename : dom/src/threads/test/test_navigator.html => dom/workers/test/test_navigator.html rename : dom/src/threads/test/test_newError.html => dom/workers/test/test_newError.html rename : dom/src/threads/test/test_recursion.html => dom/workers/test/test_recursion.html rename : dom/src/threads/test/test_relativeLoad.html => dom/workers/test/test_relativeLoad.html rename : dom/src/threads/test/test_simpleThread.html => dom/workers/test/test_simpleThread.html rename : dom/src/threads/test/test_suspend.html => dom/workers/test/test_suspend.html rename : dom/src/threads/test/test_terminate.html => dom/workers/test/test_terminate.html rename : dom/src/threads/test/test_threadErrors.html => dom/workers/test/test_threadErrors.html rename : dom/src/threads/test/test_threadTimeouts.html => dom/workers/test/test_threadTimeouts.html rename : dom/src/threads/test/test_throwingOnerror.html => dom/workers/test/test_throwingOnerror.html rename : dom/src/threads/test/test_xhr.html => dom/workers/test/test_xhr.html rename : dom/src/threads/test/test_xhrAbort.html => dom/workers/test/test_xhrAbort.html rename : dom/src/threads/test/threadErrors_worker1.js => dom/workers/test/threadErrors_worker1.js rename : dom/src/threads/test/threadErrors_worker2.js => dom/workers/test/threadErrors_worker2.js rename : dom/src/threads/test/threadErrors_worker3.js => dom/workers/test/threadErrors_worker3.js rename : dom/src/threads/test/threadErrors_worker4.js => dom/workers/test/threadErrors_worker4.js rename : dom/src/threads/test/threadTimeouts_worker.js => dom/workers/test/threadTimeouts_worker.js rename : dom/src/threads/test/throwingOnerror_worker.js => dom/workers/test/throwingOnerror_worker.js rename : dom/src/threads/test/xhrAbort_worker.js => dom/workers/test/xhrAbort_worker.js rename : dom/src/threads/test/xhr_worker.js => dom/workers/test/xhr_worker.js
2011-07-17 12:09:13 -07:00
if (NS_FAILED(xpc->JSValToVariant(cx, &body,
getter_AddRefs(variant)))) {
error = INVALID_STATE_ERR;
}
}
else {
error = DATA_CLONE_ERR;
}
mBody.clear();
Bug 649537 - 'Workers: Make one OS thread and JS runtime per worker, and lose XPConnect'. r=sicking+mrbkap. * * * Bug 649537 - 'Workers: Make one OS thread and JS runtime per worker, and lose XPConnect'. r=sicking+mrbkap. Add workaround for bug 666963. --HG-- rename : dom/src/threads/Makefile.in => dom/workers/Makefile.in rename : dom/src/threads/test/Makefile.in => dom/workers/test/Makefile.in rename : dom/src/threads/test/WorkerTest.jsm => dom/workers/test/WorkerTest.jsm rename : dom/src/threads/test/WorkerTest_badworker.js => dom/workers/test/WorkerTest_badworker.js rename : dom/src/threads/test/WorkerTest_subworker.js => dom/workers/test/WorkerTest_subworker.js rename : dom/src/threads/test/WorkerTest_worker.js => dom/workers/test/WorkerTest_worker.js rename : dom/src/threads/test/atob_worker.js => dom/workers/test/atob_worker.js rename : dom/src/threads/test/chromeWorker_subworker.js => dom/workers/test/chromeWorker_subworker.js rename : dom/src/threads/test/chromeWorker_worker.js => dom/workers/test/chromeWorker_worker.js rename : dom/src/threads/test/closeOnGC_server.sjs => dom/workers/test/closeOnGC_server.sjs rename : dom/src/threads/test/closeOnGC_worker.js => dom/workers/test/closeOnGC_worker.js rename : dom/src/threads/test/close_worker.js => dom/workers/test/close_worker.js rename : dom/src/threads/test/fibonacci_worker.js => dom/workers/test/fibonacci_worker.js rename : dom/src/threads/test/importScripts_worker.js => dom/workers/test/importScripts_worker.js rename : dom/src/threads/test/importScripts_worker_imported1.js => dom/workers/test/importScripts_worker_imported1.js rename : dom/src/threads/test/importScripts_worker_imported2.js => dom/workers/test/importScripts_worker_imported2.js rename : dom/src/threads/test/importScripts_worker_imported3.js => dom/workers/test/importScripts_worker_imported3.js rename : dom/src/threads/test/importScripts_worker_imported4.js => dom/workers/test/importScripts_worker_imported4.js rename : dom/src/threads/test/json_worker.js => dom/workers/test/json_worker.js rename : dom/src/threads/test/location_worker.js => dom/workers/test/location_worker.js rename : dom/src/threads/test/longThread_worker.js => dom/workers/test/longThread_worker.js rename : dom/src/threads/test/navigator_worker.js => dom/workers/test/navigator_worker.js rename : dom/src/threads/test/newError_worker.js => dom/workers/test/newError_worker.js rename : dom/src/threads/test/recursion_worker.js => dom/workers/test/recursion_worker.js rename : dom/src/threads/test/relativeLoad_import.js => dom/workers/test/relativeLoad_import.js rename : dom/src/threads/test/relativeLoad_sub_import.js => dom/workers/test/relativeLoad_sub_import.js rename : dom/src/threads/test/relativeLoad_sub_worker.js => dom/workers/test/relativeLoad_sub_worker.js rename : dom/src/threads/test/relativeLoad_sub_worker2.js => dom/workers/test/relativeLoad_sub_worker2.js rename : dom/src/threads/test/relativeLoad_worker.js => dom/workers/test/relativeLoad_worker.js rename : dom/src/threads/test/relativeLoad_worker2.js => dom/workers/test/relativeLoad_worker2.js rename : dom/src/threads/test/simpleThread_worker.js => dom/workers/test/simpleThread_worker.js rename : dom/src/threads/test/suspend_iframe.html => dom/workers/test/suspend_iframe.html rename : dom/src/threads/test/suspend_worker.js => dom/workers/test/suspend_worker.js rename : dom/src/threads/test/terminate_worker.js => dom/workers/test/terminate_worker.js rename : dom/src/threads/test/testXHR.txt => dom/workers/test/testXHR.txt rename : dom/src/threads/test/test_404.html => dom/workers/test/test_404.html rename : dom/src/threads/test/test_atob.html => dom/workers/test/test_atob.html rename : dom/src/threads/test/test_chromeWorker.html => dom/workers/test/test_chromeWorker.html rename : dom/src/threads/test/test_chromeWorker.xul => dom/workers/test/test_chromeWorker.xul rename : dom/src/threads/test/test_chromeWorkerJSM.xul => dom/workers/test/test_chromeWorkerJSM.xul rename : dom/src/threads/test/test_close.html => dom/workers/test/test_close.html rename : dom/src/threads/test/test_closeOnGC.html => dom/workers/test/test_closeOnGC.html rename : dom/src/threads/test/test_errorPropagation.html => dom/workers/test/test_errorPropagation.html rename : dom/src/threads/test/test_fibonacci.html => dom/workers/test/test_fibonacci.html rename : dom/src/threads/test/test_importScripts.html => dom/workers/test/test_importScripts.html rename : dom/src/threads/test/test_json.html => dom/workers/test/test_json.html rename : dom/src/threads/test/test_location.html => dom/workers/test/test_location.html rename : dom/src/threads/test/test_longThread.html => dom/workers/test/test_longThread.html rename : dom/src/threads/test/test_navigator.html => dom/workers/test/test_navigator.html rename : dom/src/threads/test/test_newError.html => dom/workers/test/test_newError.html rename : dom/src/threads/test/test_recursion.html => dom/workers/test/test_recursion.html rename : dom/src/threads/test/test_relativeLoad.html => dom/workers/test/test_relativeLoad.html rename : dom/src/threads/test/test_simpleThread.html => dom/workers/test/test_simpleThread.html rename : dom/src/threads/test/test_suspend.html => dom/workers/test/test_suspend.html rename : dom/src/threads/test/test_terminate.html => dom/workers/test/test_terminate.html rename : dom/src/threads/test/test_threadErrors.html => dom/workers/test/test_threadErrors.html rename : dom/src/threads/test/test_threadTimeouts.html => dom/workers/test/test_threadTimeouts.html rename : dom/src/threads/test/test_throwingOnerror.html => dom/workers/test/test_throwingOnerror.html rename : dom/src/threads/test/test_xhr.html => dom/workers/test/test_xhr.html rename : dom/src/threads/test/test_xhrAbort.html => dom/workers/test/test_xhrAbort.html rename : dom/src/threads/test/threadErrors_worker1.js => dom/workers/test/threadErrors_worker1.js rename : dom/src/threads/test/threadErrors_worker2.js => dom/workers/test/threadErrors_worker2.js rename : dom/src/threads/test/threadErrors_worker3.js => dom/workers/test/threadErrors_worker3.js rename : dom/src/threads/test/threadErrors_worker4.js => dom/workers/test/threadErrors_worker4.js rename : dom/src/threads/test/threadTimeouts_worker.js => dom/workers/test/threadTimeouts_worker.js rename : dom/src/threads/test/throwingOnerror_worker.js => dom/workers/test/throwingOnerror_worker.js rename : dom/src/threads/test/xhrAbort_worker.js => dom/workers/test/xhrAbort_worker.js rename : dom/src/threads/test/xhr_worker.js => dom/workers/test/xhr_worker.js
2011-07-17 12:09:13 -07:00
if (error) {
return error;
}
}
if (mHasUploadListeners) {
NS_ASSERTION(!mProxy->mUploadEventListenersAttached, "Huh?!");
if (!mProxy->AddRemoveEventListeners(true, true)) {
NS_ERROR("This should never fail!");
}
}
nsresult rv = mProxy->mXHR->Send(variant);
if (NS_SUCCEEDED(rv) && !mHasUploadListeners) {
NS_ASSERTION(!mProxy->mUploadEventListenersAttached, "Huh?!");
if (!mProxy->AddRemoveEventListeners(true, true)) {
NS_ERROR("This should never fail!");
}
}
return GetDOMExceptionCodeFromResult(rv);
}
};
class SendAsBinaryRunnable : public WorkerThreadProxySyncRunnable
{
nsString mBody;
PRUint32 mSyncQueueKey;
bool mHasUploadListeners;
public:
SendAsBinaryRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
const nsString& aBody, PRUint32 aSyncQueueKey,
bool aHasUploadListeners)
: WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mBody(aBody),
mSyncQueueKey(aSyncQueueKey), mHasUploadListeners(aHasUploadListeners)
{ }
intN
MainThreadRun()
{
NS_ASSERTION(!mProxy->mWorkerPrivate, "Should be null!");
mProxy->mWorkerPrivate = mWorkerPrivate;
NS_ASSERTION(mProxy->mSyncQueueKey == PR_UINT32_MAX, "Should be unset!");
mProxy->mSyncQueueKey = mSyncQueueKey;
if (mHasUploadListeners) {
NS_ASSERTION(!mProxy->mUploadEventListenersAttached, "Huh?!");
if (!mProxy->AddRemoveEventListeners(true, true)) {
NS_ERROR("This should never fail!");
}
}
nsresult rv = mProxy->mXHR->SendAsBinary(mBody);
if (NS_SUCCEEDED(rv) && !mHasUploadListeners) {
NS_ASSERTION(!mProxy->mUploadEventListenersAttached, "Huh?!");
if (!mProxy->AddRemoveEventListeners(true, true)) {
NS_ERROR("This should never fail!");
}
}
return GetDOMExceptionCodeFromResult(rv);
}
};
class SetRequestHeaderRunnable : public WorkerThreadProxySyncRunnable
{
nsCString mHeader;
nsCString mValue;
public:
SetRequestHeaderRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
const nsCString& aHeader, const nsCString& aValue)
: WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mHeader(aHeader),
mValue(aValue)
{ }
intN
MainThreadRun()
{
nsresult rv = mProxy->mXHR->SetRequestHeader(mHeader, mValue);
return GetDOMExceptionCodeFromResult(rv);
}
};
class OverrideMimeTypeRunnable : public WorkerThreadProxySyncRunnable
{
nsCString mMimeType;
public:
OverrideMimeTypeRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
const nsCString& aMimeType)
: WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mMimeType(aMimeType)
{ }
intN
MainThreadRun()
{
nsresult rv = mProxy->mXHR->OverrideMimeType(mMimeType);
return GetDOMExceptionCodeFromResult(rv);
}
};
Bug 649537 - 'Workers: Make one OS thread and JS runtime per worker, and lose XPConnect'. r=sicking+mrbkap. * * * Bug 649537 - 'Workers: Make one OS thread and JS runtime per worker, and lose XPConnect'. r=sicking+mrbkap. Add workaround for bug 666963. --HG-- rename : dom/src/threads/Makefile.in => dom/workers/Makefile.in rename : dom/src/threads/test/Makefile.in => dom/workers/test/Makefile.in rename : dom/src/threads/test/WorkerTest.jsm => dom/workers/test/WorkerTest.jsm rename : dom/src/threads/test/WorkerTest_badworker.js => dom/workers/test/WorkerTest_badworker.js rename : dom/src/threads/test/WorkerTest_subworker.js => dom/workers/test/WorkerTest_subworker.js rename : dom/src/threads/test/WorkerTest_worker.js => dom/workers/test/WorkerTest_worker.js rename : dom/src/threads/test/atob_worker.js => dom/workers/test/atob_worker.js rename : dom/src/threads/test/chromeWorker_subworker.js => dom/workers/test/chromeWorker_subworker.js rename : dom/src/threads/test/chromeWorker_worker.js => dom/workers/test/chromeWorker_worker.js rename : dom/src/threads/test/closeOnGC_server.sjs => dom/workers/test/closeOnGC_server.sjs rename : dom/src/threads/test/closeOnGC_worker.js => dom/workers/test/closeOnGC_worker.js rename : dom/src/threads/test/close_worker.js => dom/workers/test/close_worker.js rename : dom/src/threads/test/fibonacci_worker.js => dom/workers/test/fibonacci_worker.js rename : dom/src/threads/test/importScripts_worker.js => dom/workers/test/importScripts_worker.js rename : dom/src/threads/test/importScripts_worker_imported1.js => dom/workers/test/importScripts_worker_imported1.js rename : dom/src/threads/test/importScripts_worker_imported2.js => dom/workers/test/importScripts_worker_imported2.js rename : dom/src/threads/test/importScripts_worker_imported3.js => dom/workers/test/importScripts_worker_imported3.js rename : dom/src/threads/test/importScripts_worker_imported4.js => dom/workers/test/importScripts_worker_imported4.js rename : dom/src/threads/test/json_worker.js => dom/workers/test/json_worker.js rename : dom/src/threads/test/location_worker.js => dom/workers/test/location_worker.js rename : dom/src/threads/test/longThread_worker.js => dom/workers/test/longThread_worker.js rename : dom/src/threads/test/navigator_worker.js => dom/workers/test/navigator_worker.js rename : dom/src/threads/test/newError_worker.js => dom/workers/test/newError_worker.js rename : dom/src/threads/test/recursion_worker.js => dom/workers/test/recursion_worker.js rename : dom/src/threads/test/relativeLoad_import.js => dom/workers/test/relativeLoad_import.js rename : dom/src/threads/test/relativeLoad_sub_import.js => dom/workers/test/relativeLoad_sub_import.js rename : dom/src/threads/test/relativeLoad_sub_worker.js => dom/workers/test/relativeLoad_sub_worker.js rename : dom/src/threads/test/relativeLoad_sub_worker2.js => dom/workers/test/relativeLoad_sub_worker2.js rename : dom/src/threads/test/relativeLoad_worker.js => dom/workers/test/relativeLoad_worker.js rename : dom/src/threads/test/relativeLoad_worker2.js => dom/workers/test/relativeLoad_worker2.js rename : dom/src/threads/test/simpleThread_worker.js => dom/workers/test/simpleThread_worker.js rename : dom/src/threads/test/suspend_iframe.html => dom/workers/test/suspend_iframe.html rename : dom/src/threads/test/suspend_worker.js => dom/workers/test/suspend_worker.js rename : dom/src/threads/test/terminate_worker.js => dom/workers/test/terminate_worker.js rename : dom/src/threads/test/testXHR.txt => dom/workers/test/testXHR.txt rename : dom/src/threads/test/test_404.html => dom/workers/test/test_404.html rename : dom/src/threads/test/test_atob.html => dom/workers/test/test_atob.html rename : dom/src/threads/test/test_chromeWorker.html => dom/workers/test/test_chromeWorker.html rename : dom/src/threads/test/test_chromeWorker.xul => dom/workers/test/test_chromeWorker.xul rename : dom/src/threads/test/test_chromeWorkerJSM.xul => dom/workers/test/test_chromeWorkerJSM.xul rename : dom/src/threads/test/test_close.html => dom/workers/test/test_close.html rename : dom/src/threads/test/test_closeOnGC.html => dom/workers/test/test_closeOnGC.html rename : dom/src/threads/test/test_errorPropagation.html => dom/workers/test/test_errorPropagation.html rename : dom/src/threads/test/test_fibonacci.html => dom/workers/test/test_fibonacci.html rename : dom/src/threads/test/test_importScripts.html => dom/workers/test/test_importScripts.html rename : dom/src/threads/test/test_json.html => dom/workers/test/test_json.html rename : dom/src/threads/test/test_location.html => dom/workers/test/test_location.html rename : dom/src/threads/test/test_longThread.html => dom/workers/test/test_longThread.html rename : dom/src/threads/test/test_navigator.html => dom/workers/test/test_navigator.html rename : dom/src/threads/test/test_newError.html => dom/workers/test/test_newError.html rename : dom/src/threads/test/test_recursion.html => dom/workers/test/test_recursion.html rename : dom/src/threads/test/test_relativeLoad.html => dom/workers/test/test_relativeLoad.html rename : dom/src/threads/test/test_simpleThread.html => dom/workers/test/test_simpleThread.html rename : dom/src/threads/test/test_suspend.html => dom/workers/test/test_suspend.html rename : dom/src/threads/test/test_terminate.html => dom/workers/test/test_terminate.html rename : dom/src/threads/test/test_threadErrors.html => dom/workers/test/test_threadErrors.html rename : dom/src/threads/test/test_threadTimeouts.html => dom/workers/test/test_threadTimeouts.html rename : dom/src/threads/test/test_throwingOnerror.html => dom/workers/test/test_throwingOnerror.html rename : dom/src/threads/test/test_xhr.html => dom/workers/test/test_xhr.html rename : dom/src/threads/test/test_xhrAbort.html => dom/workers/test/test_xhrAbort.html rename : dom/src/threads/test/threadErrors_worker1.js => dom/workers/test/threadErrors_worker1.js rename : dom/src/threads/test/threadErrors_worker2.js => dom/workers/test/threadErrors_worker2.js rename : dom/src/threads/test/threadErrors_worker3.js => dom/workers/test/threadErrors_worker3.js rename : dom/src/threads/test/threadErrors_worker4.js => dom/workers/test/threadErrors_worker4.js rename : dom/src/threads/test/threadTimeouts_worker.js => dom/workers/test/threadTimeouts_worker.js rename : dom/src/threads/test/throwingOnerror_worker.js => dom/workers/test/throwingOnerror_worker.js rename : dom/src/threads/test/xhrAbort_worker.js => dom/workers/test/xhrAbort_worker.js rename : dom/src/threads/test/xhr_worker.js => dom/workers/test/xhr_worker.js
2011-07-17 12:09:13 -07:00
} // anonymous namespace
void
Proxy::Teardown()
{
AssertIsOnMainThread();
if (mXHR) {
Reset();
AddRemoveEventListeners(false, false);
mXHR->Abort();
mXHRUpload = nsnull;
mXHR = nsnull;
}
}
bool
Proxy::AddRemoveEventListeners(bool aUpload, bool aAdd)
{
AssertIsOnMainThread();
NS_ASSERTION(!aUpload ||
(mUploadEventListenersAttached && !aAdd) ||
(!mUploadEventListenersAttached && aAdd),
"Messed up logic for upload listeners!");
nsCOMPtr<nsIDOMEventTarget> target =
aUpload ?
do_QueryInterface(mXHRUpload) :
do_QueryInterface(static_cast<nsIXMLHttpRequest*>(mXHR.get()));
NS_ASSERTION(target, "This should never fail!");
PRUint32 lastEventType = aUpload ? STRING_LAST_EVENTTARGET : STRING_LAST_XHR;
nsAutoString eventType;
for (PRUint32 index = 0; index <= lastEventType; index++) {
eventType = NS_ConvertASCIItoUTF16(sEventStrings[index]);
if (aAdd) {
if (NS_FAILED(target->AddEventListener(eventType, this, false))) {
return false;
}
}
else if (NS_FAILED(target->RemoveEventListener(eventType, this, false))) {
return false;
}
}
if (aUpload) {
mUploadEventListenersAttached = aAdd;
}
return true;
}
NS_IMPL_THREADSAFE_ISUPPORTS1(Proxy, nsIDOMEventListener)
NS_IMETHODIMP
Proxy::HandleEvent(nsIDOMEvent* aEvent)
{
AssertIsOnMainThread();
if (!mWorkerPrivate || !mXMLHttpRequestPrivate) {
NS_ERROR("Shouldn't get here!");
return NS_OK;
}
nsString type;
if (NS_FAILED(aEvent->GetType(type))) {
NS_WARNING("Failed to get event type!");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDOMEventTarget> target;
if (NS_FAILED(aEvent->GetTarget(getter_AddRefs(target)))) {
NS_WARNING("Failed to get target!");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIXMLHttpRequestUpload> uploadTarget = do_QueryInterface(target);
nsCOMPtr<nsIDOMProgressEvent> progressEvent = do_QueryInterface(aEvent);
nsRefPtr<EventRunnable> runnable;
if (progressEvent) {
bool lengthComputable;
Bug 649537 - 'Workers: Make one OS thread and JS runtime per worker, and lose XPConnect'. r=sicking+mrbkap. * * * Bug 649537 - 'Workers: Make one OS thread and JS runtime per worker, and lose XPConnect'. r=sicking+mrbkap. Add workaround for bug 666963. --HG-- rename : dom/src/threads/Makefile.in => dom/workers/Makefile.in rename : dom/src/threads/test/Makefile.in => dom/workers/test/Makefile.in rename : dom/src/threads/test/WorkerTest.jsm => dom/workers/test/WorkerTest.jsm rename : dom/src/threads/test/WorkerTest_badworker.js => dom/workers/test/WorkerTest_badworker.js rename : dom/src/threads/test/WorkerTest_subworker.js => dom/workers/test/WorkerTest_subworker.js rename : dom/src/threads/test/WorkerTest_worker.js => dom/workers/test/WorkerTest_worker.js rename : dom/src/threads/test/atob_worker.js => dom/workers/test/atob_worker.js rename : dom/src/threads/test/chromeWorker_subworker.js => dom/workers/test/chromeWorker_subworker.js rename : dom/src/threads/test/chromeWorker_worker.js => dom/workers/test/chromeWorker_worker.js rename : dom/src/threads/test/closeOnGC_server.sjs => dom/workers/test/closeOnGC_server.sjs rename : dom/src/threads/test/closeOnGC_worker.js => dom/workers/test/closeOnGC_worker.js rename : dom/src/threads/test/close_worker.js => dom/workers/test/close_worker.js rename : dom/src/threads/test/fibonacci_worker.js => dom/workers/test/fibonacci_worker.js rename : dom/src/threads/test/importScripts_worker.js => dom/workers/test/importScripts_worker.js rename : dom/src/threads/test/importScripts_worker_imported1.js => dom/workers/test/importScripts_worker_imported1.js rename : dom/src/threads/test/importScripts_worker_imported2.js => dom/workers/test/importScripts_worker_imported2.js rename : dom/src/threads/test/importScripts_worker_imported3.js => dom/workers/test/importScripts_worker_imported3.js rename : dom/src/threads/test/importScripts_worker_imported4.js => dom/workers/test/importScripts_worker_imported4.js rename : dom/src/threads/test/json_worker.js => dom/workers/test/json_worker.js rename : dom/src/threads/test/location_worker.js => dom/workers/test/location_worker.js rename : dom/src/threads/test/longThread_worker.js => dom/workers/test/longThread_worker.js rename : dom/src/threads/test/navigator_worker.js => dom/workers/test/navigator_worker.js rename : dom/src/threads/test/newError_worker.js => dom/workers/test/newError_worker.js rename : dom/src/threads/test/recursion_worker.js => dom/workers/test/recursion_worker.js rename : dom/src/threads/test/relativeLoad_import.js => dom/workers/test/relativeLoad_import.js rename : dom/src/threads/test/relativeLoad_sub_import.js => dom/workers/test/relativeLoad_sub_import.js rename : dom/src/threads/test/relativeLoad_sub_worker.js => dom/workers/test/relativeLoad_sub_worker.js rename : dom/src/threads/test/relativeLoad_sub_worker2.js => dom/workers/test/relativeLoad_sub_worker2.js rename : dom/src/threads/test/relativeLoad_worker.js => dom/workers/test/relativeLoad_worker.js rename : dom/src/threads/test/relativeLoad_worker2.js => dom/workers/test/relativeLoad_worker2.js rename : dom/src/threads/test/simpleThread_worker.js => dom/workers/test/simpleThread_worker.js rename : dom/src/threads/test/suspend_iframe.html => dom/workers/test/suspend_iframe.html rename : dom/src/threads/test/suspend_worker.js => dom/workers/test/suspend_worker.js rename : dom/src/threads/test/terminate_worker.js => dom/workers/test/terminate_worker.js rename : dom/src/threads/test/testXHR.txt => dom/workers/test/testXHR.txt rename : dom/src/threads/test/test_404.html => dom/workers/test/test_404.html rename : dom/src/threads/test/test_atob.html => dom/workers/test/test_atob.html rename : dom/src/threads/test/test_chromeWorker.html => dom/workers/test/test_chromeWorker.html rename : dom/src/threads/test/test_chromeWorker.xul => dom/workers/test/test_chromeWorker.xul rename : dom/src/threads/test/test_chromeWorkerJSM.xul => dom/workers/test/test_chromeWorkerJSM.xul rename : dom/src/threads/test/test_close.html => dom/workers/test/test_close.html rename : dom/src/threads/test/test_closeOnGC.html => dom/workers/test/test_closeOnGC.html rename : dom/src/threads/test/test_errorPropagation.html => dom/workers/test/test_errorPropagation.html rename : dom/src/threads/test/test_fibonacci.html => dom/workers/test/test_fibonacci.html rename : dom/src/threads/test/test_importScripts.html => dom/workers/test/test_importScripts.html rename : dom/src/threads/test/test_json.html => dom/workers/test/test_json.html rename : dom/src/threads/test/test_location.html => dom/workers/test/test_location.html rename : dom/src/threads/test/test_longThread.html => dom/workers/test/test_longThread.html rename : dom/src/threads/test/test_navigator.html => dom/workers/test/test_navigator.html rename : dom/src/threads/test/test_newError.html => dom/workers/test/test_newError.html rename : dom/src/threads/test/test_recursion.html => dom/workers/test/test_recursion.html rename : dom/src/threads/test/test_relativeLoad.html => dom/workers/test/test_relativeLoad.html rename : dom/src/threads/test/test_simpleThread.html => dom/workers/test/test_simpleThread.html rename : dom/src/threads/test/test_suspend.html => dom/workers/test/test_suspend.html rename : dom/src/threads/test/test_terminate.html => dom/workers/test/test_terminate.html rename : dom/src/threads/test/test_threadErrors.html => dom/workers/test/test_threadErrors.html rename : dom/src/threads/test/test_threadTimeouts.html => dom/workers/test/test_threadTimeouts.html rename : dom/src/threads/test/test_throwingOnerror.html => dom/workers/test/test_throwingOnerror.html rename : dom/src/threads/test/test_xhr.html => dom/workers/test/test_xhr.html rename : dom/src/threads/test/test_xhrAbort.html => dom/workers/test/test_xhrAbort.html rename : dom/src/threads/test/threadErrors_worker1.js => dom/workers/test/threadErrors_worker1.js rename : dom/src/threads/test/threadErrors_worker2.js => dom/workers/test/threadErrors_worker2.js rename : dom/src/threads/test/threadErrors_worker3.js => dom/workers/test/threadErrors_worker3.js rename : dom/src/threads/test/threadErrors_worker4.js => dom/workers/test/threadErrors_worker4.js rename : dom/src/threads/test/threadTimeouts_worker.js => dom/workers/test/threadTimeouts_worker.js rename : dom/src/threads/test/throwingOnerror_worker.js => dom/workers/test/throwingOnerror_worker.js rename : dom/src/threads/test/xhrAbort_worker.js => dom/workers/test/xhrAbort_worker.js rename : dom/src/threads/test/xhr_worker.js => dom/workers/test/xhr_worker.js
2011-07-17 12:09:13 -07:00
PRUint64 loaded, total;
if (NS_FAILED(progressEvent->GetLengthComputable(&lengthComputable)) ||
NS_FAILED(progressEvent->GetLoaded(&loaded)) ||
NS_FAILED(progressEvent->GetTotal(&total))) {
NS_WARNING("Bad progress event!");
return NS_ERROR_FAILURE;
}
runnable = new EventRunnable(this, !!uploadTarget, type, lengthComputable,
loaded, total);
}
else {
runnable = new EventRunnable(this, !!uploadTarget, type);
}
runnable->Dispatch(nsnull);
if (!uploadTarget) {
if (type.EqualsASCII(sEventStrings[STRING_loadstart])) {
NS_ASSERTION(!mMainThreadSeenLoadStart, "Huh?!");
mMainThreadSeenLoadStart = true;
}
else if (mMainThreadSeenLoadStart &&
type.EqualsASCII(sEventStrings[STRING_loadend])) {
mMainThreadSeenLoadStart = false;
nsRefPtr<LoadStartDetectionRunnable> runnable =
new LoadStartDetectionRunnable(this, mXMLHttpRequestPrivate);
if (NS_FAILED(NS_DispatchToCurrentThread(runnable))) {
NS_WARNING("Failed to dispatch LoadStartDetectionRunnable!");
}
}
}
return NS_OK;
}
XMLHttpRequestPrivate::XMLHttpRequestPrivate(JSObject* aObj,
WorkerPrivate* aWorkerPrivate)
: mJSObject(aObj), mUploadJSObject(nsnull), mWorkerPrivate(aWorkerPrivate),
mJSObjectRootCount(0), mMultipart(false), mBackgroundRequest(false),
mWithCredentials(false), mCanceled(false)
{
mWorkerPrivate->AssertIsOnWorkerThread();
MOZ_COUNT_CTOR(mozilla::dom::workers::xhr::XMLHttpRequestPrivate);
}
XMLHttpRequestPrivate::~XMLHttpRequestPrivate()
{
mWorkerPrivate->AssertIsOnWorkerThread();
NS_ASSERTION(!mJSObjectRootCount, "Huh?!");
MOZ_COUNT_DTOR(mozilla::dom::workers::xhr::XMLHttpRequestPrivate);
}
void
XMLHttpRequestPrivate::ReleaseProxy()
{
// Can't assert that we're on the worker thread here because mWorkerPrivate
// may be gone.
if (mProxy) {
// Don't let any more events run.
mProxy->mOuterChannelId++;
nsCOMPtr<nsIRunnable> runnable = new TeardownRunnable(mProxy);
NS_ASSERTION(!mProxy, "Should have swapped!");
if (NS_FAILED(NS_DispatchToMainThread(runnable, NS_DISPATCH_NORMAL))) {
NS_ERROR("Failed to dispatch teardown runnable!");
}
}
}
bool
XMLHttpRequestPrivate::RootJSObject(JSContext* aCx)
{
mWorkerPrivate->AssertIsOnWorkerThread();
if (!mJSObjectRootCount) {
if (!JS_AddNamedObjectRoot(aCx, &mJSObject,
"XMLHttpRequestPrivate mJSObject")) {
return false;
}
}
mJSObjectRootCount++;
return true;
}
void
XMLHttpRequestPrivate::UnrootJSObject(JSContext* aCx)
{
mWorkerPrivate->AssertIsOnWorkerThread();
NS_ASSERTION(mJSObjectRootCount, "Mismatched calls to UnrootJSObject!");
mJSObjectRootCount--;
if (!mJSObjectRootCount && !JS_RemoveObjectRoot(aCx, &mJSObject)) {
NS_ERROR("JS_RemoveObjectRoot failed!");
}
}
bool
XMLHttpRequestPrivate::Notify(JSContext* aCx, Status aStatus)
{
mWorkerPrivate->AssertIsOnWorkerThread();
if (aStatus >= Canceling && !mCanceled) {
mCanceled = true;
ReleaseProxy();
}
return true;
}
bool
XMLHttpRequestPrivate::SetMultipart(JSContext* aCx, jsval *aVp)
{
mWorkerPrivate->AssertIsOnWorkerThread();
if (mCanceled) {
return false;
}
JSBool multipart;
if (!JS_ValueToBoolean(aCx, *aVp, &multipart)) {
return false;
}
*aVp = multipart ? JSVAL_TRUE : JSVAL_FALSE;
if (!mProxy) {
mMultipart = !!multipart;
return true;
}
nsRefPtr<SetMultipartRunnable> runnable =
new SetMultipartRunnable(mWorkerPrivate, mProxy, multipart);
if (!runnable->Dispatch(aCx)) {
return false;
}
return true;
}
bool
XMLHttpRequestPrivate::SetMozBackgroundRequest(JSContext* aCx, jsval *aVp)
{
mWorkerPrivate->AssertIsOnWorkerThread();
if (mCanceled) {
return false;
}
JSBool backgroundRequest;
if (!JS_ValueToBoolean(aCx, *aVp, &backgroundRequest)) {
return false;
}
*aVp = backgroundRequest ? JSVAL_TRUE : JSVAL_FALSE;
if (!mProxy) {
mBackgroundRequest = !!backgroundRequest;
return true;
}
nsRefPtr<SetBackgroundRequestRunnable> runnable =
new SetBackgroundRequestRunnable(mWorkerPrivate, mProxy, backgroundRequest);
if (!runnable->Dispatch(aCx)) {
return false;
}
return true;
}
bool
XMLHttpRequestPrivate::SetWithCredentials(JSContext* aCx, jsval *aVp)
{
mWorkerPrivate->AssertIsOnWorkerThread();
if (mCanceled) {
return false;
}
JSBool withCredentials;
if (!JS_ValueToBoolean(aCx, *aVp, &withCredentials)) {
return false;
}
*aVp = withCredentials ? JSVAL_TRUE : JSVAL_FALSE;
if (!mProxy) {
mWithCredentials = !!withCredentials;
return true;
}
nsRefPtr<SetWithCredentialsRunnable> runnable =
new SetWithCredentialsRunnable(mWorkerPrivate, mProxy, withCredentials);
if (!runnable->Dispatch(aCx)) {
return false;
}
return true;
}
bool
XMLHttpRequestPrivate::Abort(JSContext* aCx)
{
mWorkerPrivate->AssertIsOnWorkerThread();
if (mCanceled) {
return false;
}
if (mProxy) {
if (!MaybeDispatchPrematureAbortEvents(aCx, false)) {
return false;
}
}
else {
return true;
}
mProxy->mOuterChannelId++;
nsRefPtr<AbortRunnable> runnable = new AbortRunnable(mWorkerPrivate, mProxy);
return runnable->Dispatch(aCx);
}
JSString*
XMLHttpRequestPrivate::GetAllResponseHeaders(JSContext* aCx)
{
mWorkerPrivate->AssertIsOnWorkerThread();
if (mCanceled) {
return false;
}
if (!mProxy) {
ThrowDOMExceptionForCode(aCx, INVALID_STATE_ERR);
return false;
}
nsCString responseHeaders;
nsRefPtr<GetAllResponseHeadersRunnable> runnable =
new GetAllResponseHeadersRunnable(mWorkerPrivate, mProxy, responseHeaders);
if (!runnable->Dispatch(aCx)) {
return false;
}
return JS_NewStringCopyN(aCx, responseHeaders.get(),
responseHeaders.Length());
}
JSString*
XMLHttpRequestPrivate::GetResponseHeader(JSContext* aCx, JSString* aHeader)
{
mWorkerPrivate->AssertIsOnWorkerThread();
if (mCanceled) {
return false;
}
if (!mProxy) {
ThrowDOMExceptionForCode(aCx, INVALID_STATE_ERR);
return false;
}
nsDependentJSString header;
if (!header.init(aCx, aHeader)) {
return false;
}
nsCString value;
nsRefPtr<GetResponseHeaderRunnable> runnable =
new GetResponseHeaderRunnable(mWorkerPrivate, mProxy,
NS_ConvertUTF16toUTF8(header), value);
if (!runnable->Dispatch(aCx)) {
return false;
}
return JS_NewStringCopyN(aCx, value.get(), value.Length());
}
bool
XMLHttpRequestPrivate::Open(JSContext* aCx, JSString* aMethod, JSString* aURL,
bool aAsync, JSString* aUser, JSString* aPassword)
{
mWorkerPrivate->AssertIsOnWorkerThread();
if (mCanceled) {
return false;
}
nsDependentJSString method, url, user, password;
if (!method.init(aCx, aMethod) || !url.init(aCx, aURL) ||
!user.init(aCx, aUser) || !password.init(aCx, aPassword)) {
return false;
}
if (mProxy) {
if (!MaybeDispatchPrematureAbortEvents(aCx, true)) {
return false;
}
}
else {
mProxy = new Proxy(this);
}
mProxy->mOuterChannelId++;
nsRefPtr<OpenRunnable> runnable =
new OpenRunnable(mWorkerPrivate, mProxy, NS_ConvertUTF16toUTF8(method),
NS_ConvertUTF16toUTF8(url), user, password, mMultipart,
mBackgroundRequest, mWithCredentials);
// These were only useful before we had a proxy. From here on out changing
// those values makes no difference.
mMultipart = mBackgroundRequest = mWithCredentials = false;
if (!runnable->Dispatch(aCx)) {
ReleaseProxy();
return false;
}
mProxy->mIsSyncXHR = !aAsync;
return true;
}
bool
XMLHttpRequestPrivate::Send(JSContext* aCx, bool aHasBody, jsval aBody)
{
mWorkerPrivate->AssertIsOnWorkerThread();
if (mCanceled) {
return false;
}
JSAutoStructuredCloneBuffer buffer;
if (aHasBody) {
if (JSVAL_IS_PRIMITIVE(aBody) ||
!js_IsArrayBuffer(JSVAL_TO_OBJECT(aBody))) {
JSString* bodyStr = JS_ValueToString(aCx, aBody);
if (!bodyStr) {
return false;
}
aBody = STRING_TO_JSVAL(bodyStr);
}
if (!buffer.write(aCx, aBody)) {
return false;
}
}
if (!mProxy) {
ThrowDOMExceptionForCode(aCx, INVALID_STATE_ERR);
return false;
}
bool hasUploadListeners = false;
if (mUploadJSObject) {
events::EventTarget* target =
events::EventTarget::FromJSObject(aCx, mUploadJSObject);
NS_ASSERTION(target, "This should never be null!");
hasUploadListeners = target->HasListeners();
}
if (!RootJSObject(aCx)) {
return false;
}
if (!mWorkerPrivate->AddFeature(aCx, this)) {
UnrootJSObject(aCx);
return false;
}
PRUint32 syncQueueKey = PR_UINT32_MAX;
if (mProxy->mIsSyncXHR) {
syncQueueKey = mWorkerPrivate->CreateNewSyncLoop();
}
nsRefPtr<SendRunnable> runnable =
new SendRunnable(mWorkerPrivate, mProxy, buffer, syncQueueKey,
hasUploadListeners);
if (!runnable->Dispatch(aCx)) {
UnrootJSObject(aCx);
mWorkerPrivate->RemoveFeature(aCx, this);
return false;
}
// The event loop was spun above, make sure we aren't canceled already.
if (mCanceled) {
return false;
}
return mProxy->mIsSyncXHR ?
mWorkerPrivate->RunSyncLoop(aCx, syncQueueKey) :
true;
}
bool
XMLHttpRequestPrivate::SendAsBinary(JSContext* aCx, JSString* aBody)
{
mWorkerPrivate->AssertIsOnWorkerThread();
if (mCanceled) {
return false;
}
if (!mProxy) {
ThrowDOMExceptionForCode(aCx, INVALID_STATE_ERR);
return false;
}
nsDependentJSString body;
if (!body.init(aCx, aBody)) {
return false;
}
bool hasUploadListeners = false;
if (mUploadJSObject) {
events::EventTarget* target =
events::EventTarget::FromJSObject(aCx, mUploadJSObject);
NS_ASSERTION(target, "This should never be null!");
hasUploadListeners = target->HasListeners();
}
if (!RootJSObject(aCx)) {
return false;
}
PRUint32 syncQueueKey = PR_UINT32_MAX;
if (mProxy->mIsSyncXHR) {
syncQueueKey = mWorkerPrivate->CreateNewSyncLoop();
}
nsRefPtr<SendAsBinaryRunnable> runnable =
new SendAsBinaryRunnable(mWorkerPrivate, mProxy, body, syncQueueKey,
hasUploadListeners);
if (!runnable->Dispatch(aCx)) {
UnrootJSObject(aCx);
return false;
}
// The event loop was spun above, make sure we aren't canceled already.
if (mCanceled) {
return false;
}
return mProxy->mIsSyncXHR ?
mWorkerPrivate->RunSyncLoop(aCx, syncQueueKey) :
true;
}
bool
XMLHttpRequestPrivate::SetRequestHeader(JSContext* aCx, JSString* aHeader,
JSString* aValue)
{
mWorkerPrivate->AssertIsOnWorkerThread();
if (mCanceled) {
return false;
}
if (!mProxy) {
ThrowDOMExceptionForCode(aCx, INVALID_STATE_ERR);
return false;
}
nsDependentJSString header, value;
if (!header.init(aCx, aHeader) || !value.init(aCx, aValue)) {
return false;
}
nsRefPtr<SetRequestHeaderRunnable> runnable =
new SetRequestHeaderRunnable(mWorkerPrivate, mProxy,
NS_ConvertUTF16toUTF8(header),
NS_ConvertUTF16toUTF8(value));
return runnable->Dispatch(aCx);
}
bool
XMLHttpRequestPrivate::OverrideMimeType(JSContext* aCx, JSString* aMimeType)
{
mWorkerPrivate->AssertIsOnWorkerThread();
if (mCanceled) {
return false;
}
// We're supposed to throw if the state is not OPENED or HEADERS_RECEIVED. We
// can detect OPENED really easily but we can't detect HEADERS_RECEIVED in a
// non-racy way until the XHR state machine actually runs on this thread
// (bug 671047). For now we're going to let this work only if the Send()
// method has not been called.
if (!mProxy || SendInProgress()) {
ThrowDOMExceptionForCode(aCx, INVALID_STATE_ERR);
return false;
}
nsDependentJSString mimeType;
if (!mimeType.init(aCx, aMimeType)) {
return false;
}
nsRefPtr<OverrideMimeTypeRunnable> runnable =
new OverrideMimeTypeRunnable(mWorkerPrivate, mProxy,
NS_ConvertUTF16toUTF8(mimeType));
return runnable->Dispatch(aCx);
}
Bug 649537 - 'Workers: Make one OS thread and JS runtime per worker, and lose XPConnect'. r=sicking+mrbkap. * * * Bug 649537 - 'Workers: Make one OS thread and JS runtime per worker, and lose XPConnect'. r=sicking+mrbkap. Add workaround for bug 666963. --HG-- rename : dom/src/threads/Makefile.in => dom/workers/Makefile.in rename : dom/src/threads/test/Makefile.in => dom/workers/test/Makefile.in rename : dom/src/threads/test/WorkerTest.jsm => dom/workers/test/WorkerTest.jsm rename : dom/src/threads/test/WorkerTest_badworker.js => dom/workers/test/WorkerTest_badworker.js rename : dom/src/threads/test/WorkerTest_subworker.js => dom/workers/test/WorkerTest_subworker.js rename : dom/src/threads/test/WorkerTest_worker.js => dom/workers/test/WorkerTest_worker.js rename : dom/src/threads/test/atob_worker.js => dom/workers/test/atob_worker.js rename : dom/src/threads/test/chromeWorker_subworker.js => dom/workers/test/chromeWorker_subworker.js rename : dom/src/threads/test/chromeWorker_worker.js => dom/workers/test/chromeWorker_worker.js rename : dom/src/threads/test/closeOnGC_server.sjs => dom/workers/test/closeOnGC_server.sjs rename : dom/src/threads/test/closeOnGC_worker.js => dom/workers/test/closeOnGC_worker.js rename : dom/src/threads/test/close_worker.js => dom/workers/test/close_worker.js rename : dom/src/threads/test/fibonacci_worker.js => dom/workers/test/fibonacci_worker.js rename : dom/src/threads/test/importScripts_worker.js => dom/workers/test/importScripts_worker.js rename : dom/src/threads/test/importScripts_worker_imported1.js => dom/workers/test/importScripts_worker_imported1.js rename : dom/src/threads/test/importScripts_worker_imported2.js => dom/workers/test/importScripts_worker_imported2.js rename : dom/src/threads/test/importScripts_worker_imported3.js => dom/workers/test/importScripts_worker_imported3.js rename : dom/src/threads/test/importScripts_worker_imported4.js => dom/workers/test/importScripts_worker_imported4.js rename : dom/src/threads/test/json_worker.js => dom/workers/test/json_worker.js rename : dom/src/threads/test/location_worker.js => dom/workers/test/location_worker.js rename : dom/src/threads/test/longThread_worker.js => dom/workers/test/longThread_worker.js rename : dom/src/threads/test/navigator_worker.js => dom/workers/test/navigator_worker.js rename : dom/src/threads/test/newError_worker.js => dom/workers/test/newError_worker.js rename : dom/src/threads/test/recursion_worker.js => dom/workers/test/recursion_worker.js rename : dom/src/threads/test/relativeLoad_import.js => dom/workers/test/relativeLoad_import.js rename : dom/src/threads/test/relativeLoad_sub_import.js => dom/workers/test/relativeLoad_sub_import.js rename : dom/src/threads/test/relativeLoad_sub_worker.js => dom/workers/test/relativeLoad_sub_worker.js rename : dom/src/threads/test/relativeLoad_sub_worker2.js => dom/workers/test/relativeLoad_sub_worker2.js rename : dom/src/threads/test/relativeLoad_worker.js => dom/workers/test/relativeLoad_worker.js rename : dom/src/threads/test/relativeLoad_worker2.js => dom/workers/test/relativeLoad_worker2.js rename : dom/src/threads/test/simpleThread_worker.js => dom/workers/test/simpleThread_worker.js rename : dom/src/threads/test/suspend_iframe.html => dom/workers/test/suspend_iframe.html rename : dom/src/threads/test/suspend_worker.js => dom/workers/test/suspend_worker.js rename : dom/src/threads/test/terminate_worker.js => dom/workers/test/terminate_worker.js rename : dom/src/threads/test/testXHR.txt => dom/workers/test/testXHR.txt rename : dom/src/threads/test/test_404.html => dom/workers/test/test_404.html rename : dom/src/threads/test/test_atob.html => dom/workers/test/test_atob.html rename : dom/src/threads/test/test_chromeWorker.html => dom/workers/test/test_chromeWorker.html rename : dom/src/threads/test/test_chromeWorker.xul => dom/workers/test/test_chromeWorker.xul rename : dom/src/threads/test/test_chromeWorkerJSM.xul => dom/workers/test/test_chromeWorkerJSM.xul rename : dom/src/threads/test/test_close.html => dom/workers/test/test_close.html rename : dom/src/threads/test/test_closeOnGC.html => dom/workers/test/test_closeOnGC.html rename : dom/src/threads/test/test_errorPropagation.html => dom/workers/test/test_errorPropagation.html rename : dom/src/threads/test/test_fibonacci.html => dom/workers/test/test_fibonacci.html rename : dom/src/threads/test/test_importScripts.html => dom/workers/test/test_importScripts.html rename : dom/src/threads/test/test_json.html => dom/workers/test/test_json.html rename : dom/src/threads/test/test_location.html => dom/workers/test/test_location.html rename : dom/src/threads/test/test_longThread.html => dom/workers/test/test_longThread.html rename : dom/src/threads/test/test_navigator.html => dom/workers/test/test_navigator.html rename : dom/src/threads/test/test_newError.html => dom/workers/test/test_newError.html rename : dom/src/threads/test/test_recursion.html => dom/workers/test/test_recursion.html rename : dom/src/threads/test/test_relativeLoad.html => dom/workers/test/test_relativeLoad.html rename : dom/src/threads/test/test_simpleThread.html => dom/workers/test/test_simpleThread.html rename : dom/src/threads/test/test_suspend.html => dom/workers/test/test_suspend.html rename : dom/src/threads/test/test_terminate.html => dom/workers/test/test_terminate.html rename : dom/src/threads/test/test_threadErrors.html => dom/workers/test/test_threadErrors.html rename : dom/src/threads/test/test_threadTimeouts.html => dom/workers/test/test_threadTimeouts.html rename : dom/src/threads/test/test_throwingOnerror.html => dom/workers/test/test_throwingOnerror.html rename : dom/src/threads/test/test_xhr.html => dom/workers/test/test_xhr.html rename : dom/src/threads/test/test_xhrAbort.html => dom/workers/test/test_xhrAbort.html rename : dom/src/threads/test/threadErrors_worker1.js => dom/workers/test/threadErrors_worker1.js rename : dom/src/threads/test/threadErrors_worker2.js => dom/workers/test/threadErrors_worker2.js rename : dom/src/threads/test/threadErrors_worker3.js => dom/workers/test/threadErrors_worker3.js rename : dom/src/threads/test/threadErrors_worker4.js => dom/workers/test/threadErrors_worker4.js rename : dom/src/threads/test/threadTimeouts_worker.js => dom/workers/test/threadTimeouts_worker.js rename : dom/src/threads/test/throwingOnerror_worker.js => dom/workers/test/throwingOnerror_worker.js rename : dom/src/threads/test/xhrAbort_worker.js => dom/workers/test/xhrAbort_worker.js rename : dom/src/threads/test/xhr_worker.js => dom/workers/test/xhr_worker.js
2011-07-17 12:09:13 -07:00
bool
XMLHttpRequestPrivate::MaybeDispatchPrematureAbortEvents(JSContext* aCx,
bool aFromOpen)
{
mWorkerPrivate->AssertIsOnWorkerThread();
NS_ASSERTION(mProxy, "Must have a proxy here!");
xhr::StateData state = {
JSVAL_VOID, JSVAL_VOID, JSVAL_VOID, INT_TO_JSVAL(4),
false, false, false, false
};
if (mProxy->mSeenUploadLoadStart) {
JSObject* target = mProxy->mXMLHttpRequestPrivate->GetUploadJSObject();
NS_ASSERTION(target, "Must have a target!");
if (!xhr::UpdateXHRState(aCx, target, true, state) ||
Bug 649537 - 'Workers: Make one OS thread and JS runtime per worker, and lose XPConnect'. r=sicking+mrbkap. * * * Bug 649537 - 'Workers: Make one OS thread and JS runtime per worker, and lose XPConnect'. r=sicking+mrbkap. Add workaround for bug 666963. --HG-- rename : dom/src/threads/Makefile.in => dom/workers/Makefile.in rename : dom/src/threads/test/Makefile.in => dom/workers/test/Makefile.in rename : dom/src/threads/test/WorkerTest.jsm => dom/workers/test/WorkerTest.jsm rename : dom/src/threads/test/WorkerTest_badworker.js => dom/workers/test/WorkerTest_badworker.js rename : dom/src/threads/test/WorkerTest_subworker.js => dom/workers/test/WorkerTest_subworker.js rename : dom/src/threads/test/WorkerTest_worker.js => dom/workers/test/WorkerTest_worker.js rename : dom/src/threads/test/atob_worker.js => dom/workers/test/atob_worker.js rename : dom/src/threads/test/chromeWorker_subworker.js => dom/workers/test/chromeWorker_subworker.js rename : dom/src/threads/test/chromeWorker_worker.js => dom/workers/test/chromeWorker_worker.js rename : dom/src/threads/test/closeOnGC_server.sjs => dom/workers/test/closeOnGC_server.sjs rename : dom/src/threads/test/closeOnGC_worker.js => dom/workers/test/closeOnGC_worker.js rename : dom/src/threads/test/close_worker.js => dom/workers/test/close_worker.js rename : dom/src/threads/test/fibonacci_worker.js => dom/workers/test/fibonacci_worker.js rename : dom/src/threads/test/importScripts_worker.js => dom/workers/test/importScripts_worker.js rename : dom/src/threads/test/importScripts_worker_imported1.js => dom/workers/test/importScripts_worker_imported1.js rename : dom/src/threads/test/importScripts_worker_imported2.js => dom/workers/test/importScripts_worker_imported2.js rename : dom/src/threads/test/importScripts_worker_imported3.js => dom/workers/test/importScripts_worker_imported3.js rename : dom/src/threads/test/importScripts_worker_imported4.js => dom/workers/test/importScripts_worker_imported4.js rename : dom/src/threads/test/json_worker.js => dom/workers/test/json_worker.js rename : dom/src/threads/test/location_worker.js => dom/workers/test/location_worker.js rename : dom/src/threads/test/longThread_worker.js => dom/workers/test/longThread_worker.js rename : dom/src/threads/test/navigator_worker.js => dom/workers/test/navigator_worker.js rename : dom/src/threads/test/newError_worker.js => dom/workers/test/newError_worker.js rename : dom/src/threads/test/recursion_worker.js => dom/workers/test/recursion_worker.js rename : dom/src/threads/test/relativeLoad_import.js => dom/workers/test/relativeLoad_import.js rename : dom/src/threads/test/relativeLoad_sub_import.js => dom/workers/test/relativeLoad_sub_import.js rename : dom/src/threads/test/relativeLoad_sub_worker.js => dom/workers/test/relativeLoad_sub_worker.js rename : dom/src/threads/test/relativeLoad_sub_worker2.js => dom/workers/test/relativeLoad_sub_worker2.js rename : dom/src/threads/test/relativeLoad_worker.js => dom/workers/test/relativeLoad_worker.js rename : dom/src/threads/test/relativeLoad_worker2.js => dom/workers/test/relativeLoad_worker2.js rename : dom/src/threads/test/simpleThread_worker.js => dom/workers/test/simpleThread_worker.js rename : dom/src/threads/test/suspend_iframe.html => dom/workers/test/suspend_iframe.html rename : dom/src/threads/test/suspend_worker.js => dom/workers/test/suspend_worker.js rename : dom/src/threads/test/terminate_worker.js => dom/workers/test/terminate_worker.js rename : dom/src/threads/test/testXHR.txt => dom/workers/test/testXHR.txt rename : dom/src/threads/test/test_404.html => dom/workers/test/test_404.html rename : dom/src/threads/test/test_atob.html => dom/workers/test/test_atob.html rename : dom/src/threads/test/test_chromeWorker.html => dom/workers/test/test_chromeWorker.html rename : dom/src/threads/test/test_chromeWorker.xul => dom/workers/test/test_chromeWorker.xul rename : dom/src/threads/test/test_chromeWorkerJSM.xul => dom/workers/test/test_chromeWorkerJSM.xul rename : dom/src/threads/test/test_close.html => dom/workers/test/test_close.html rename : dom/src/threads/test/test_closeOnGC.html => dom/workers/test/test_closeOnGC.html rename : dom/src/threads/test/test_errorPropagation.html => dom/workers/test/test_errorPropagation.html rename : dom/src/threads/test/test_fibonacci.html => dom/workers/test/test_fibonacci.html rename : dom/src/threads/test/test_importScripts.html => dom/workers/test/test_importScripts.html rename : dom/src/threads/test/test_json.html => dom/workers/test/test_json.html rename : dom/src/threads/test/test_location.html => dom/workers/test/test_location.html rename : dom/src/threads/test/test_longThread.html => dom/workers/test/test_longThread.html rename : dom/src/threads/test/test_navigator.html => dom/workers/test/test_navigator.html rename : dom/src/threads/test/test_newError.html => dom/workers/test/test_newError.html rename : dom/src/threads/test/test_recursion.html => dom/workers/test/test_recursion.html rename : dom/src/threads/test/test_relativeLoad.html => dom/workers/test/test_relativeLoad.html rename : dom/src/threads/test/test_simpleThread.html => dom/workers/test/test_simpleThread.html rename : dom/src/threads/test/test_suspend.html => dom/workers/test/test_suspend.html rename : dom/src/threads/test/test_terminate.html => dom/workers/test/test_terminate.html rename : dom/src/threads/test/test_threadErrors.html => dom/workers/test/test_threadErrors.html rename : dom/src/threads/test/test_threadTimeouts.html => dom/workers/test/test_threadTimeouts.html rename : dom/src/threads/test/test_throwingOnerror.html => dom/workers/test/test_throwingOnerror.html rename : dom/src/threads/test/test_xhr.html => dom/workers/test/test_xhr.html rename : dom/src/threads/test/test_xhrAbort.html => dom/workers/test/test_xhrAbort.html rename : dom/src/threads/test/threadErrors_worker1.js => dom/workers/test/threadErrors_worker1.js rename : dom/src/threads/test/threadErrors_worker2.js => dom/workers/test/threadErrors_worker2.js rename : dom/src/threads/test/threadErrors_worker3.js => dom/workers/test/threadErrors_worker3.js rename : dom/src/threads/test/threadErrors_worker4.js => dom/workers/test/threadErrors_worker4.js rename : dom/src/threads/test/threadTimeouts_worker.js => dom/workers/test/threadTimeouts_worker.js rename : dom/src/threads/test/throwingOnerror_worker.js => dom/workers/test/throwingOnerror_worker.js rename : dom/src/threads/test/xhrAbort_worker.js => dom/workers/test/xhrAbort_worker.js rename : dom/src/threads/test/xhr_worker.js => dom/workers/test/xhr_worker.js
2011-07-17 12:09:13 -07:00
!DispatchPrematureAbortEvent(aCx, target, STRING_abort, true) ||
!DispatchPrematureAbortEvent(aCx, target, STRING_loadend, true)) {
return false;
}
mProxy->mSeenUploadLoadStart = false;
}
if (mProxy->mSeenLoadStart) {
JSObject* target = mProxy->mXMLHttpRequestPrivate->GetJSObject();
NS_ASSERTION(target, "Must have a target!");
if (!xhr::UpdateXHRState(aCx, target, false, state) ||
Bug 649537 - 'Workers: Make one OS thread and JS runtime per worker, and lose XPConnect'. r=sicking+mrbkap. * * * Bug 649537 - 'Workers: Make one OS thread and JS runtime per worker, and lose XPConnect'. r=sicking+mrbkap. Add workaround for bug 666963. --HG-- rename : dom/src/threads/Makefile.in => dom/workers/Makefile.in rename : dom/src/threads/test/Makefile.in => dom/workers/test/Makefile.in rename : dom/src/threads/test/WorkerTest.jsm => dom/workers/test/WorkerTest.jsm rename : dom/src/threads/test/WorkerTest_badworker.js => dom/workers/test/WorkerTest_badworker.js rename : dom/src/threads/test/WorkerTest_subworker.js => dom/workers/test/WorkerTest_subworker.js rename : dom/src/threads/test/WorkerTest_worker.js => dom/workers/test/WorkerTest_worker.js rename : dom/src/threads/test/atob_worker.js => dom/workers/test/atob_worker.js rename : dom/src/threads/test/chromeWorker_subworker.js => dom/workers/test/chromeWorker_subworker.js rename : dom/src/threads/test/chromeWorker_worker.js => dom/workers/test/chromeWorker_worker.js rename : dom/src/threads/test/closeOnGC_server.sjs => dom/workers/test/closeOnGC_server.sjs rename : dom/src/threads/test/closeOnGC_worker.js => dom/workers/test/closeOnGC_worker.js rename : dom/src/threads/test/close_worker.js => dom/workers/test/close_worker.js rename : dom/src/threads/test/fibonacci_worker.js => dom/workers/test/fibonacci_worker.js rename : dom/src/threads/test/importScripts_worker.js => dom/workers/test/importScripts_worker.js rename : dom/src/threads/test/importScripts_worker_imported1.js => dom/workers/test/importScripts_worker_imported1.js rename : dom/src/threads/test/importScripts_worker_imported2.js => dom/workers/test/importScripts_worker_imported2.js rename : dom/src/threads/test/importScripts_worker_imported3.js => dom/workers/test/importScripts_worker_imported3.js rename : dom/src/threads/test/importScripts_worker_imported4.js => dom/workers/test/importScripts_worker_imported4.js rename : dom/src/threads/test/json_worker.js => dom/workers/test/json_worker.js rename : dom/src/threads/test/location_worker.js => dom/workers/test/location_worker.js rename : dom/src/threads/test/longThread_worker.js => dom/workers/test/longThread_worker.js rename : dom/src/threads/test/navigator_worker.js => dom/workers/test/navigator_worker.js rename : dom/src/threads/test/newError_worker.js => dom/workers/test/newError_worker.js rename : dom/src/threads/test/recursion_worker.js => dom/workers/test/recursion_worker.js rename : dom/src/threads/test/relativeLoad_import.js => dom/workers/test/relativeLoad_import.js rename : dom/src/threads/test/relativeLoad_sub_import.js => dom/workers/test/relativeLoad_sub_import.js rename : dom/src/threads/test/relativeLoad_sub_worker.js => dom/workers/test/relativeLoad_sub_worker.js rename : dom/src/threads/test/relativeLoad_sub_worker2.js => dom/workers/test/relativeLoad_sub_worker2.js rename : dom/src/threads/test/relativeLoad_worker.js => dom/workers/test/relativeLoad_worker.js rename : dom/src/threads/test/relativeLoad_worker2.js => dom/workers/test/relativeLoad_worker2.js rename : dom/src/threads/test/simpleThread_worker.js => dom/workers/test/simpleThread_worker.js rename : dom/src/threads/test/suspend_iframe.html => dom/workers/test/suspend_iframe.html rename : dom/src/threads/test/suspend_worker.js => dom/workers/test/suspend_worker.js rename : dom/src/threads/test/terminate_worker.js => dom/workers/test/terminate_worker.js rename : dom/src/threads/test/testXHR.txt => dom/workers/test/testXHR.txt rename : dom/src/threads/test/test_404.html => dom/workers/test/test_404.html rename : dom/src/threads/test/test_atob.html => dom/workers/test/test_atob.html rename : dom/src/threads/test/test_chromeWorker.html => dom/workers/test/test_chromeWorker.html rename : dom/src/threads/test/test_chromeWorker.xul => dom/workers/test/test_chromeWorker.xul rename : dom/src/threads/test/test_chromeWorkerJSM.xul => dom/workers/test/test_chromeWorkerJSM.xul rename : dom/src/threads/test/test_close.html => dom/workers/test/test_close.html rename : dom/src/threads/test/test_closeOnGC.html => dom/workers/test/test_closeOnGC.html rename : dom/src/threads/test/test_errorPropagation.html => dom/workers/test/test_errorPropagation.html rename : dom/src/threads/test/test_fibonacci.html => dom/workers/test/test_fibonacci.html rename : dom/src/threads/test/test_importScripts.html => dom/workers/test/test_importScripts.html rename : dom/src/threads/test/test_json.html => dom/workers/test/test_json.html rename : dom/src/threads/test/test_location.html => dom/workers/test/test_location.html rename : dom/src/threads/test/test_longThread.html => dom/workers/test/test_longThread.html rename : dom/src/threads/test/test_navigator.html => dom/workers/test/test_navigator.html rename : dom/src/threads/test/test_newError.html => dom/workers/test/test_newError.html rename : dom/src/threads/test/test_recursion.html => dom/workers/test/test_recursion.html rename : dom/src/threads/test/test_relativeLoad.html => dom/workers/test/test_relativeLoad.html rename : dom/src/threads/test/test_simpleThread.html => dom/workers/test/test_simpleThread.html rename : dom/src/threads/test/test_suspend.html => dom/workers/test/test_suspend.html rename : dom/src/threads/test/test_terminate.html => dom/workers/test/test_terminate.html rename : dom/src/threads/test/test_threadErrors.html => dom/workers/test/test_threadErrors.html rename : dom/src/threads/test/test_threadTimeouts.html => dom/workers/test/test_threadTimeouts.html rename : dom/src/threads/test/test_throwingOnerror.html => dom/workers/test/test_throwingOnerror.html rename : dom/src/threads/test/test_xhr.html => dom/workers/test/test_xhr.html rename : dom/src/threads/test/test_xhrAbort.html => dom/workers/test/test_xhrAbort.html rename : dom/src/threads/test/threadErrors_worker1.js => dom/workers/test/threadErrors_worker1.js rename : dom/src/threads/test/threadErrors_worker2.js => dom/workers/test/threadErrors_worker2.js rename : dom/src/threads/test/threadErrors_worker3.js => dom/workers/test/threadErrors_worker3.js rename : dom/src/threads/test/threadErrors_worker4.js => dom/workers/test/threadErrors_worker4.js rename : dom/src/threads/test/threadTimeouts_worker.js => dom/workers/test/threadTimeouts_worker.js rename : dom/src/threads/test/throwingOnerror_worker.js => dom/workers/test/throwingOnerror_worker.js rename : dom/src/threads/test/xhrAbort_worker.js => dom/workers/test/xhrAbort_worker.js rename : dom/src/threads/test/xhr_worker.js => dom/workers/test/xhr_worker.js
2011-07-17 12:09:13 -07:00
!DispatchPrematureAbortEvent(aCx, target, STRING_readystatechange,
false)) {
return false;
}
if (aFromOpen) {
if (!DispatchPrematureAbortEvent(aCx, target, STRING_abort, false) ||
!DispatchPrematureAbortEvent(aCx, target, STRING_loadend, false)) {
return false;
}
}
mProxy->mSeenLoadStart = false;
}
return true;
}
bool
XMLHttpRequestPrivate::DispatchPrematureAbortEvent(JSContext* aCx,
JSObject* aTarget,
PRUint64 aEventType,
bool aUploadTarget)
{
mWorkerPrivate->AssertIsOnWorkerThread();
NS_ASSERTION(mProxy, "Must have a proxy here!");
NS_ASSERTION(aTarget, "Don't call me without a target!");
NS_ASSERTION(aEventType <= STRING_COUNT, "Bad string index!");
JSString* type = JS_NewStringCopyZ(aCx, sEventStrings[aEventType]);
if (!type) {
return false;
}
JSObject* event;
if (aEventType == STRING_readystatechange) {
event = events::CreateGenericEvent(aCx, type, false, false, false);
}
else {
if (aUploadTarget) {
event = events::CreateProgressEvent(aCx, type,
mProxy->mLastUploadLengthComputable,
mProxy->mLastUploadLoaded,
mProxy->mLastUploadTotal);
}
else {
event = events::CreateProgressEvent(aCx, type,
mProxy->mLastLengthComputable,
mProxy->mLastLoaded,
mProxy->mLastTotal);
}
}
if (!event) {
return false;
}
bool dummy;
return events::DispatchEventToTarget(aCx, aTarget, event, &dummy);
}