2008-09-08 10:48:14 -07:00
|
|
|
/* -*- Mode: c++; c-basic-offset: 4; 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 worker threads.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is
|
|
|
|
* Mozilla Corporation.
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 2008
|
|
|
|
* 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 ***** */
|
|
|
|
|
|
|
|
#ifndef __NSDOMWORKERSCRIPTLOADER_H__
|
|
|
|
#define __NSDOMWORKERSCRIPTLOADER_H__
|
|
|
|
|
|
|
|
// Bases
|
2008-11-04 18:58:24 -08:00
|
|
|
#include "nsThreadUtils.h"
|
2008-09-08 10:48:14 -07:00
|
|
|
#include "nsIStreamLoader.h"
|
|
|
|
|
|
|
|
// Interfaces
|
|
|
|
#include "nsIChannel.h"
|
|
|
|
#include "nsIURI.h"
|
|
|
|
|
|
|
|
// Other includes
|
|
|
|
#include "jsapi.h"
|
|
|
|
#include "nsAutoPtr.h"
|
2008-11-04 15:36:19 -08:00
|
|
|
#include "nsAutoJSObjectHolder.h"
|
2008-09-08 10:48:14 -07:00
|
|
|
#include "nsCOMPtr.h"
|
|
|
|
#include "nsStringGlue.h"
|
|
|
|
#include "nsTArray.h"
|
|
|
|
#include "prlock.h"
|
|
|
|
|
2008-11-04 18:58:24 -08:00
|
|
|
// DOMWorker includes
|
|
|
|
#include "nsDOMWorkerThread.h"
|
2008-09-08 10:48:14 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This class takes a list of script URLs, downloads the scripts, compiles the
|
|
|
|
* scripts, and then finally executes them. Due to platform limitations all
|
|
|
|
* network operations must happen on the main thread so this object sends events
|
|
|
|
* back and forth from the worker thread to the main thread. The flow goes like
|
|
|
|
* this:
|
|
|
|
*
|
|
|
|
* 1. (Worker thread) nsDOMWorkerScriptLoader created.
|
|
|
|
* 2. (Worker thread) LoadScript(s) called. Some simple argument validation is
|
|
|
|
* performed (currently limited to ensuring that all
|
|
|
|
* arguments are strings). nsDOMWorkerScriptLoader is then
|
|
|
|
* dispatched to the main thread.
|
|
|
|
* 3. (Main thread) Arguments validated as URIs, security checks performed,
|
|
|
|
* content policy consulted. Network loads begin.
|
|
|
|
* 4. (Necko thread) Necko stuff!
|
|
|
|
* 5. (Main thread) Completed downloads are packaged in a ScriptCompiler
|
|
|
|
* runnable and sent to the worker thread.
|
|
|
|
* 6. (Worker thread) ScriptCompiler runnables are processed (i.e. their
|
|
|
|
* scripts are compiled) in the order in which the necko
|
|
|
|
* downloads completed.
|
|
|
|
* 7. (Worker thread) After all loads complete and all compilation succeeds
|
|
|
|
* the scripts are executed in the order that the URLs were
|
|
|
|
* given to LoadScript(s).
|
|
|
|
*
|
|
|
|
* Currently if *anything* after 2 fails then we cancel any pending loads and
|
|
|
|
* bail out entirely.
|
|
|
|
*/
|
2008-11-04 18:58:24 -08:00
|
|
|
class nsDOMWorkerScriptLoader : public nsRunnable,
|
2008-09-08 10:48:14 -07:00
|
|
|
public nsIStreamLoaderObserver
|
|
|
|
{
|
|
|
|
friend class AutoSuspendWorkerEvents;
|
2008-11-04 18:58:24 -08:00
|
|
|
friend class nsDOMWorkerFunctions;
|
|
|
|
friend class nsDOMWorkerThread;
|
2008-09-08 10:48:14 -07:00
|
|
|
friend class ScriptLoaderRunnable;
|
|
|
|
|
|
|
|
public:
|
|
|
|
NS_DECL_ISUPPORTS_INHERITED
|
|
|
|
NS_DECL_NSIRUNNABLE
|
|
|
|
NS_DECL_NSISTREAMLOADEROBSERVER
|
|
|
|
|
2008-11-04 18:58:24 -08:00
|
|
|
nsDOMWorkerScriptLoader();
|
2008-09-08 10:48:14 -07:00
|
|
|
|
2008-11-04 18:58:24 -08:00
|
|
|
nsresult LoadScripts(nsDOMWorkerThread* aWorker,
|
|
|
|
JSContext* aCx,
|
2008-09-08 10:48:14 -07:00
|
|
|
const nsTArray<nsString>& aURLs);
|
|
|
|
|
2008-11-04 18:58:24 -08:00
|
|
|
nsresult LoadScript(nsDOMWorkerThread* aWorker,
|
|
|
|
JSContext* aCx,
|
|
|
|
const nsString& aURL);
|
2008-09-08 10:48:14 -07:00
|
|
|
|
2008-11-04 18:58:24 -08:00
|
|
|
void Cancel();
|
2008-09-08 10:48:14 -07:00
|
|
|
|
|
|
|
private:
|
2008-11-04 18:58:24 -08:00
|
|
|
~nsDOMWorkerScriptLoader();
|
2008-09-08 10:48:14 -07:00
|
|
|
|
2008-11-04 18:58:24 -08:00
|
|
|
nsresult DoRunLoop();
|
|
|
|
nsresult VerifyScripts();
|
|
|
|
nsresult ExecuteScripts();
|
2008-09-08 10:48:14 -07:00
|
|
|
|
|
|
|
nsresult RunInternal();
|
|
|
|
|
|
|
|
nsresult OnStreamCompleteInternal(nsIStreamLoader* aLoader,
|
|
|
|
nsISupports* aContext,
|
|
|
|
nsresult aStatus,
|
|
|
|
PRUint32 aStringLen,
|
|
|
|
const PRUint8* aString);
|
|
|
|
|
|
|
|
void NotifyDone();
|
|
|
|
|
|
|
|
void SuspendWorkerEvents();
|
|
|
|
void ResumeWorkerEvents();
|
|
|
|
|
|
|
|
PRLock* Lock() {
|
|
|
|
return mWorker->Lock();
|
|
|
|
}
|
|
|
|
|
2008-11-04 18:58:24 -08:00
|
|
|
class ScriptLoaderRunnable : public nsRunnable
|
2008-09-08 10:48:14 -07:00
|
|
|
{
|
|
|
|
protected:
|
|
|
|
// Meant to be inherited.
|
|
|
|
ScriptLoaderRunnable(nsDOMWorkerScriptLoader* aLoader);
|
|
|
|
virtual ~ScriptLoaderRunnable();
|
|
|
|
|
|
|
|
public:
|
|
|
|
void Revoke();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
PRBool mRevoked;
|
|
|
|
|
|
|
|
private:
|
|
|
|
nsDOMWorkerScriptLoader* mLoader;
|
|
|
|
};
|
|
|
|
|
|
|
|
class ScriptCompiler : public ScriptLoaderRunnable
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
NS_DECL_NSIRUNNABLE
|
|
|
|
|
|
|
|
ScriptCompiler(nsDOMWorkerScriptLoader* aLoader,
|
2008-11-04 18:58:24 -08:00
|
|
|
JSContext* aCx,
|
2008-09-08 10:48:14 -07:00
|
|
|
const nsString& aScriptText,
|
|
|
|
const nsCString& aFilename,
|
2008-11-04 15:36:19 -08:00
|
|
|
nsAutoJSObjectHolder& aScriptObj);
|
2008-09-08 10:48:14 -07:00
|
|
|
|
|
|
|
private:
|
2008-11-04 18:58:24 -08:00
|
|
|
JSContext* mCx;
|
2008-09-08 10:48:14 -07:00
|
|
|
nsString mScriptText;
|
|
|
|
nsCString mFilename;
|
2008-11-04 15:36:19 -08:00
|
|
|
nsAutoJSObjectHolder& mScriptObj;
|
2008-09-08 10:48:14 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
class ScriptLoaderDone : public ScriptLoaderRunnable
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
NS_DECL_NSIRUNNABLE
|
|
|
|
|
|
|
|
ScriptLoaderDone(nsDOMWorkerScriptLoader* aLoader,
|
|
|
|
volatile PRBool* aDoneFlag);
|
|
|
|
|
|
|
|
private:
|
|
|
|
volatile PRBool* mDoneFlag;
|
|
|
|
};
|
|
|
|
|
|
|
|
class AutoSuspendWorkerEvents
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
AutoSuspendWorkerEvents(nsDOMWorkerScriptLoader* aLoader);
|
|
|
|
~AutoSuspendWorkerEvents();
|
|
|
|
|
|
|
|
private:
|
|
|
|
nsDOMWorkerScriptLoader* mLoader;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ScriptLoadInfo
|
|
|
|
{
|
|
|
|
ScriptLoadInfo() : done(PR_FALSE), result(NS_ERROR_NOT_INITIALIZED) { }
|
|
|
|
|
|
|
|
nsString url;
|
|
|
|
nsString scriptText;
|
|
|
|
PRBool done;
|
|
|
|
nsresult result;
|
|
|
|
nsCOMPtr<nsIURI> finalURI;
|
|
|
|
nsCOMPtr<nsIChannel> channel;
|
2008-11-04 15:36:19 -08:00
|
|
|
nsAutoJSObjectHolder scriptObj;
|
2008-09-08 10:48:14 -07:00
|
|
|
};
|
|
|
|
|
2008-11-04 18:58:24 -08:00
|
|
|
nsDOMWorkerThread* mWorker;
|
2008-09-08 10:48:14 -07:00
|
|
|
nsIThread* mTarget;
|
2008-11-04 18:58:24 -08:00
|
|
|
JSContext* mCx;
|
2008-09-08 10:48:14 -07:00
|
|
|
|
|
|
|
nsRefPtr<ScriptLoaderDone> mDoneRunnable;
|
|
|
|
|
|
|
|
PRUint32 mScriptCount;
|
|
|
|
nsTArray<ScriptLoadInfo> mLoadInfos;
|
|
|
|
|
2008-11-04 18:58:24 -08:00
|
|
|
PRPackedBool mCanceled;
|
|
|
|
PRPackedBool mTrackedByWorker;
|
|
|
|
|
2008-09-08 10:48:14 -07:00
|
|
|
// Protected by mWorker's lock!
|
|
|
|
nsTArray<ScriptLoaderRunnable*> mPendingRunnables;
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif /* __NSDOMWORKERSCRIPTLOADER_H__ */
|