Bug 1240365 - FileReader should use the global scope correctly in ChromeWorkers, r=smaug, r=khuey

This commit is contained in:
Andrea Marchesini 2016-01-20 18:17:57 +00:00
parent 2ffc222f5b
commit dda4662627
5 changed files with 58 additions and 26 deletions

View File

@ -98,9 +98,9 @@ FileReader::RootResultArrayBuffer()
//FileReader constructors/initializers
FileReader::FileReader(nsPIDOMWindow* aWindow,
FileReader::FileReader(nsIGlobalObject* aGlobal,
WorkerPrivate* aWorkerPrivate)
: DOMEventTargetHelper(aWindow)
: DOMEventTargetHelper(aGlobal)
, mFileData(nullptr)
, mDataLen(0)
, mDataFormat(FILE_AS_BINARY)
@ -114,8 +114,8 @@ FileReader::FileReader(nsPIDOMWindow* aWindow,
, mBusyCount(0)
, mWorkerPrivate(aWorkerPrivate)
{
MOZ_ASSERT_IF(!NS_IsMainThread(), mWorkerPrivate && !aWindow);
MOZ_ASSERT_IF(NS_IsMainThread(), !mWorkerPrivate);
MOZ_ASSERT(aGlobal);
MOZ_ASSERT(NS_IsMainThread() == !mWorkerPrivate);
SetDOMStringToNull(mResult);
}
@ -128,8 +128,7 @@ FileReader::~FileReader()
/* static */ already_AddRefed<FileReader>
FileReader::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
{
// The owner can be null when this object is used by chrome code.
nsCOMPtr<nsPIDOMWindow> owner = do_QueryInterface(aGlobal.GetAsSupports());
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
WorkerPrivate* workerPrivate = nullptr;
if (!NS_IsMainThread()) {
@ -138,14 +137,7 @@ FileReader::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
MOZ_ASSERT(workerPrivate);
}
RefPtr<FileReader> fileReader = new FileReader(owner, workerPrivate);
if (!owner && nsContentUtils::ThreadsafeIsCallerChrome()) {
// Instead of grabbing some random global from the context stack,
// let's use the default one (junk scope) for now.
// We should move away from this Init...
fileReader->BindToOwner(xpc::NativeGlobal(xpc::PrivilegedJunkScope()));
}
RefPtr<FileReader> fileReader = new FileReader(global, workerPrivate);
return fileReader.forget();
}
@ -242,17 +234,7 @@ FileReader::DoOnLoadEnd(nsresult aStatus,
switch (mDataFormat) {
case FILE_AS_ARRAYBUFFER: {
AutoJSAPI jsapi;
nsCOMPtr<nsIGlobalObject> globalObject;
if (NS_IsMainThread()) {
globalObject = do_QueryInterface(GetParentObject());
} else {
MOZ_ASSERT(mWorkerPrivate);
MOZ_ASSERT(mBusyCount);
globalObject = mWorkerPrivate->GlobalScope();
}
if (!globalObject || !jsapi.Init(globalObject)) {
if (!jsapi.Init(GetParentObject())) {
FreeFileData();
return NS_ERROR_FAILURE;
}

View File

@ -46,7 +46,7 @@ class FileReader final : public DOMEventTargetHelper,
friend class FileReaderDecreaseBusyCounter;
public:
FileReader(nsPIDOMWindow* aWindow,
FileReader(nsIGlobalObject* aGlobal,
workers::WorkerPrivate* aWorkerPrivate);
NS_DECL_ISUPPORTS_INHERITED

View File

@ -0,0 +1,8 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
self.onmessage = function(msg) {
var fr = new FileReader();
self.postMessage("OK");
};

View File

@ -0,0 +1,40 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
Components.utils.import("resource://gre/modules/Promise.jsm");
// Worker must be loaded from a chrome:// uri, not a file://
// uri, so we first need to load it.
var WORKER_SOURCE_URI = "chrome://workers/content/worker_fileReader.js";
do_load_manifest("data/chrome.manifest");
function run_test() {
run_next_test();
}
function talk_with_worker(worker) {
let deferred = Promise.defer();
worker.onmessage = function(event) {
let success = true;
if (event.data == "OK") {
deferred.resolve();
} else {
success = false;
deferred.reject(event);
}
do_check_true(success);
worker.terminate();
};
worker.onerror = function(event) {
let error = new Error(event.message, event.filename, event.lineno);
worker.terminate();
deferred.reject(error);
};
worker.postMessage("START");
return deferred.promise;
}
add_task(function test_chrome_worker() {
return talk_with_worker(new ChromeWorker(WORKER_SOURCE_URI));
});

View File

@ -4,6 +4,8 @@ tail =
skip-if = toolkit == 'android' || toolkit == 'gonk'
support-files =
data/worker.js
data/worker_fileReader.js
data/chrome.manifest
[test_workers.js]
[test_fileReader.js]