2015-05-03 22:32:37 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2011-07-17 23:09:13 +04:00
|
|
|
|
|
|
|
#ifndef mozilla_dom_workers_workerprivate_h__
|
|
|
|
#define mozilla_dom_workers_workerprivate_h__
|
|
|
|
|
|
|
|
#include "Workers.h"
|
|
|
|
|
2015-06-17 04:21:08 +03:00
|
|
|
#include "nsIContentPolicy.h"
|
2012-09-15 22:51:55 +04:00
|
|
|
#include "nsIContentSecurityPolicy.h"
|
2014-12-12 19:06:00 +03:00
|
|
|
#include "nsILoadGroup.h"
|
2014-10-27 20:00:05 +03:00
|
|
|
#include "nsIWorkerDebugger.h"
|
2012-09-05 21:47:57 +04:00
|
|
|
#include "nsPIDOMWindow.h"
|
2011-07-17 23:09:13 +04:00
|
|
|
|
|
|
|
#include "mozilla/CondVar.h"
|
2014-04-01 10:13:50 +04:00
|
|
|
#include "mozilla/DOMEventTargetHelper.h"
|
2011-07-17 23:09:13 +04:00
|
|
|
#include "mozilla/TimeStamp.h"
|
2013-06-05 18:04:23 +04:00
|
|
|
#include "mozilla/dom/BindingDeclarations.h"
|
2014-12-17 09:26:15 +03:00
|
|
|
#include "nsAutoPtr.h"
|
2013-06-05 18:04:23 +04:00
|
|
|
#include "nsCycleCollectionParticipant.h"
|
|
|
|
#include "nsDataHashtable.h"
|
|
|
|
#include "nsHashKeys.h"
|
2013-11-05 18:16:26 +04:00
|
|
|
#include "nsRefPtrHashtable.h"
|
2013-09-23 21:25:00 +04:00
|
|
|
#include "nsString.h"
|
2011-07-17 23:09:13 +04:00
|
|
|
#include "nsTArray.h"
|
2013-06-05 18:04:23 +04:00
|
|
|
#include "nsThreadUtils.h"
|
2015-04-07 20:31:51 +03:00
|
|
|
#include "nsTObserverArray.h"
|
2011-07-17 23:09:13 +04:00
|
|
|
|
|
|
|
#include "Queue.h"
|
|
|
|
#include "WorkerFeature.h"
|
|
|
|
|
2013-03-08 02:27:21 +04:00
|
|
|
class nsIChannel;
|
2011-07-17 23:09:13 +04:00
|
|
|
class nsIDocument;
|
2013-10-23 17:16:49 +04:00
|
|
|
class nsIEventTarget;
|
2011-07-17 23:09:13 +04:00
|
|
|
class nsIPrincipal;
|
|
|
|
class nsIScriptContext;
|
2015-04-24 01:59:52 +03:00
|
|
|
class nsISerializable;
|
2013-10-23 17:16:49 +04:00
|
|
|
class nsIThread;
|
2014-01-11 04:37:47 +04:00
|
|
|
class nsIThreadInternal;
|
2011-07-17 23:09:13 +04:00
|
|
|
class nsITimer;
|
2013-06-05 18:04:23 +04:00
|
|
|
class nsIURI;
|
2013-05-17 02:49:43 +04:00
|
|
|
|
|
|
|
namespace JS {
|
2014-06-19 04:57:51 +04:00
|
|
|
struct RuntimeStats;
|
2015-07-13 18:25:42 +03:00
|
|
|
} // namespace JS
|
2011-07-17 23:09:13 +04:00
|
|
|
|
2013-11-05 18:16:26 +04:00
|
|
|
namespace mozilla {
|
|
|
|
namespace dom {
|
|
|
|
class Function;
|
2015-09-16 06:27:56 +03:00
|
|
|
class MessagePort;
|
|
|
|
class MessagePortIdentifier;
|
2015-09-30 15:22:08 +03:00
|
|
|
class StructuredCloneHolder;
|
2015-07-13 18:25:42 +03:00
|
|
|
} // namespace dom
|
2014-12-17 09:26:15 +03:00
|
|
|
namespace ipc {
|
|
|
|
class PrincipalInfo;
|
2015-07-13 18:25:42 +03:00
|
|
|
} // namespace ipc
|
|
|
|
} // namespace mozilla
|
2013-11-05 18:16:26 +04:00
|
|
|
|
2013-10-23 17:16:49 +04:00
|
|
|
struct PRThread;
|
|
|
|
|
2015-03-26 22:09:45 +03:00
|
|
|
class ReportDebuggerErrorRunnable;
|
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
BEGIN_WORKERS_NAMESPACE
|
|
|
|
|
2013-10-23 17:16:49 +04:00
|
|
|
class AutoSyncLoopHolder;
|
2013-06-05 18:04:23 +04:00
|
|
|
class SharedWorker;
|
2015-03-16 23:23:42 +03:00
|
|
|
class ServiceWorkerClientInfo;
|
2013-10-23 17:16:49 +04:00
|
|
|
class WorkerControlRunnable;
|
2014-11-17 22:55:37 +03:00
|
|
|
class WorkerDebugger;
|
2015-03-04 02:51:53 +03:00
|
|
|
class WorkerDebuggerGlobalScope;
|
2013-11-05 18:16:26 +04:00
|
|
|
class WorkerGlobalScope;
|
2011-07-17 23:09:13 +04:00
|
|
|
class WorkerPrivate;
|
2013-10-23 17:16:49 +04:00
|
|
|
class WorkerRunnable;
|
2014-11-17 22:55:37 +03:00
|
|
|
class WorkerThread;
|
2011-07-17 23:09:13 +04:00
|
|
|
|
2013-02-08 15:50:00 +04:00
|
|
|
// SharedMutex is a small wrapper around an (internal) reference-counted Mutex
|
|
|
|
// object. It exists to avoid changing a lot of code to use Mutex* instead of
|
|
|
|
// Mutex&.
|
|
|
|
class SharedMutex
|
|
|
|
{
|
|
|
|
typedef mozilla::Mutex Mutex;
|
|
|
|
|
2015-03-21 19:28:04 +03:00
|
|
|
class RefCountedMutex final : public Mutex
|
2013-02-08 15:50:00 +04:00
|
|
|
{
|
|
|
|
public:
|
2014-09-02 04:49:25 +04:00
|
|
|
explicit RefCountedMutex(const char* aName)
|
2013-02-08 15:50:00 +04:00
|
|
|
: Mutex(aName)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RefCountedMutex)
|
|
|
|
|
|
|
|
private:
|
|
|
|
~RefCountedMutex()
|
|
|
|
{ }
|
|
|
|
};
|
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<RefCountedMutex> mMutex;
|
2013-02-08 15:50:00 +04:00
|
|
|
|
|
|
|
public:
|
2014-09-02 04:49:25 +04:00
|
|
|
explicit SharedMutex(const char* aName)
|
2013-02-08 15:50:00 +04:00
|
|
|
: mMutex(new RefCountedMutex(aName))
|
|
|
|
{ }
|
|
|
|
|
|
|
|
SharedMutex(SharedMutex& aOther)
|
|
|
|
: mMutex(aOther.mMutex)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
operator Mutex&()
|
|
|
|
{
|
|
|
|
return *mMutex;
|
|
|
|
}
|
|
|
|
|
|
|
|
operator const Mutex&() const
|
|
|
|
{
|
|
|
|
return *mMutex;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
AssertCurrentThreadOwns() const
|
|
|
|
{
|
|
|
|
mMutex->AssertCurrentThreadOwns();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
template <class Derived>
|
2014-04-01 10:13:50 +04:00
|
|
|
class WorkerPrivateParent : public DOMEventTargetHelper
|
2011-07-17 23:09:13 +04:00
|
|
|
{
|
2013-10-23 17:16:49 +04:00
|
|
|
protected:
|
|
|
|
class EventTarget;
|
|
|
|
friend class EventTarget;
|
|
|
|
|
2014-12-17 09:26:15 +03:00
|
|
|
typedef mozilla::ipc::PrincipalInfo PrincipalInfo;
|
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
public:
|
|
|
|
struct LocationInfo
|
|
|
|
{
|
|
|
|
nsCString mHref;
|
|
|
|
nsCString mProtocol;
|
|
|
|
nsCString mHost;
|
|
|
|
nsCString mHostname;
|
|
|
|
nsCString mPort;
|
|
|
|
nsCString mPathname;
|
|
|
|
nsCString mSearch;
|
|
|
|
nsCString mHash;
|
2014-01-31 22:22:52 +04:00
|
|
|
nsString mOrigin;
|
2011-07-17 23:09:13 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
protected:
|
2013-06-05 18:04:23 +04:00
|
|
|
typedef mozilla::ErrorResult ErrorResult;
|
|
|
|
|
2013-02-08 15:50:00 +04:00
|
|
|
SharedMutex mMutex;
|
2011-07-17 23:09:13 +04:00
|
|
|
mozilla::CondVar mCondVar;
|
2012-12-30 22:21:52 +04:00
|
|
|
mozilla::CondVar mMemoryReportCondVar;
|
2011-07-17 23:09:13 +04:00
|
|
|
|
2013-10-23 17:16:49 +04:00
|
|
|
// Protected by mMutex.
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<EventTarget> mEventTarget;
|
|
|
|
nsTArray<RefPtr<WorkerRunnable>> mPreStartRunnables;
|
2013-10-23 17:16:49 +04:00
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
private:
|
|
|
|
WorkerPrivate* mParent;
|
|
|
|
nsString mScriptURL;
|
2015-10-01 02:11:03 +03:00
|
|
|
// This is the worker name for shared workers or the worker scope
|
|
|
|
// for service workers.
|
|
|
|
nsCString mWorkerName;
|
2011-07-17 23:09:13 +04:00
|
|
|
LocationInfo mLocationInfo;
|
2013-11-05 18:16:24 +04:00
|
|
|
// The lifetime of these objects within LoadInfo is managed explicitly;
|
|
|
|
// they do not need to be cycle collected.
|
2015-02-12 12:50:05 +03:00
|
|
|
WorkerLoadInfo mLoadInfo;
|
2011-07-17 23:09:13 +04:00
|
|
|
|
2015-03-19 21:41:42 +03:00
|
|
|
Atomic<bool> mLoadingWorkerScript;
|
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
// Only used for top level workers.
|
2013-10-23 17:16:49 +04:00
|
|
|
nsTArray<nsCOMPtr<nsIRunnable>> mQueuedRunnables;
|
2011-07-17 23:09:13 +04:00
|
|
|
|
2013-05-17 02:49:43 +04:00
|
|
|
// Protected by mMutex.
|
|
|
|
JSSettings mJSSettings;
|
|
|
|
|
2013-06-05 18:04:23 +04:00
|
|
|
// Only touched on the parent thread (currently this is always the main
|
|
|
|
// thread as SharedWorkers are always top-level).
|
2015-10-18 08:24:48 +03:00
|
|
|
nsTArray<RefPtr<SharedWorker>> mSharedWorkers;
|
2013-06-05 18:04:23 +04:00
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
uint64_t mBusyCount;
|
2011-07-17 23:09:13 +04:00
|
|
|
Status mParentStatus;
|
2015-04-01 12:00:19 +03:00
|
|
|
bool mParentFrozen;
|
2015-10-07 13:20:59 +03:00
|
|
|
bool mParentSuspended;
|
2011-07-17 23:09:13 +04:00
|
|
|
bool mIsChromeWorker;
|
2012-03-31 08:42:20 +04:00
|
|
|
bool mMainThreadObjectsForgotten;
|
2013-10-31 03:40:16 +04:00
|
|
|
WorkerType mWorkerType;
|
2014-05-06 13:50:12 +04:00
|
|
|
TimeStamp mCreationTimeStamp;
|
2015-05-25 19:53:07 +03:00
|
|
|
DOMHighResTimeStamp mCreationTimeHighRes;
|
2011-07-17 23:09:13 +04:00
|
|
|
|
|
|
|
protected:
|
2014-02-02 22:08:50 +04:00
|
|
|
// The worker is owned by its thread, which is represented here. This is set
|
|
|
|
// in Construct() and emptied by WorkerFinishedRunnable, and conditionally
|
|
|
|
// traversed by the cycle collector if the busy count is zero.
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<WorkerPrivate> mSelfRef;
|
2014-02-02 22:08:50 +04:00
|
|
|
|
2013-11-05 18:16:24 +04:00
|
|
|
WorkerPrivateParent(JSContext* aCx, WorkerPrivate* aParent,
|
|
|
|
const nsAString& aScriptURL, bool aIsChromeWorker,
|
|
|
|
WorkerType aWorkerType,
|
2014-02-06 18:39:10 +04:00
|
|
|
const nsACString& aSharedWorkerName,
|
2015-02-12 12:50:05 +03:00
|
|
|
WorkerLoadInfo& aLoadInfo);
|
2011-07-17 23:09:13 +04:00
|
|
|
|
|
|
|
~WorkerPrivateParent();
|
|
|
|
|
|
|
|
private:
|
|
|
|
Derived*
|
|
|
|
ParentAsWorkerPrivate() const
|
|
|
|
{
|
|
|
|
return static_cast<Derived*>(const_cast<WorkerPrivateParent*>(this));
|
|
|
|
}
|
|
|
|
|
2012-03-19 18:34:58 +04:00
|
|
|
// aCx is null when called from the finalizer
|
2011-12-29 22:28:13 +04:00
|
|
|
bool
|
2012-03-19 18:34:58 +04:00
|
|
|
NotifyPrivate(JSContext* aCx, Status aStatus);
|
2011-12-29 22:28:13 +04:00
|
|
|
|
2012-03-19 18:34:58 +04:00
|
|
|
// aCx is null when called from the finalizer
|
2011-12-29 22:28:13 +04:00
|
|
|
bool
|
2012-03-19 18:34:58 +04:00
|
|
|
TerminatePrivate(JSContext* aCx)
|
2011-12-29 22:28:13 +04:00
|
|
|
{
|
2012-03-19 18:34:58 +04:00
|
|
|
return NotifyPrivate(aCx, Terminating);
|
2011-12-29 22:28:13 +04:00
|
|
|
}
|
|
|
|
|
2013-11-05 18:16:24 +04:00
|
|
|
void
|
2013-06-05 18:04:23 +04:00
|
|
|
PostMessageInternal(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
2015-03-16 23:23:42 +03:00
|
|
|
const Optional<Sequence<JS::Value>>& aTransferable,
|
2015-10-01 02:11:03 +03:00
|
|
|
UniquePtr<ServiceWorkerClientInfo>&& aClientInfo,
|
2013-11-05 18:16:24 +04:00
|
|
|
ErrorResult& aRv);
|
2013-06-05 18:04:23 +04:00
|
|
|
|
2013-10-23 17:16:49 +04:00
|
|
|
nsresult
|
2015-07-10 06:21:46 +03:00
|
|
|
DispatchPrivate(already_AddRefed<WorkerRunnable>&& aRunnable, nsIEventTarget* aSyncLoopTarget);
|
2013-10-23 17:16:49 +04:00
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
public:
|
2013-11-05 18:16:24 +04:00
|
|
|
virtual JSObject*
|
2015-03-21 19:28:04 +03:00
|
|
|
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
2013-11-05 18:16:24 +04:00
|
|
|
|
|
|
|
NS_DECL_ISUPPORTS_INHERITED
|
|
|
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(WorkerPrivateParent,
|
2014-04-01 10:13:50 +04:00
|
|
|
DOMEventTargetHelper)
|
2013-11-05 18:16:24 +04:00
|
|
|
|
2014-10-27 20:00:05 +03:00
|
|
|
void
|
|
|
|
EnableDebugger();
|
|
|
|
|
|
|
|
void
|
|
|
|
DisableDebugger();
|
|
|
|
|
2014-02-02 22:08:50 +04:00
|
|
|
void
|
|
|
|
ClearSelfRef()
|
|
|
|
{
|
|
|
|
AssertIsOnParentThread();
|
|
|
|
MOZ_ASSERT(mSelfRef);
|
|
|
|
mSelfRef = nullptr;
|
|
|
|
}
|
|
|
|
|
2013-10-23 17:16:49 +04:00
|
|
|
nsresult
|
2015-07-10 06:21:46 +03:00
|
|
|
Dispatch(already_AddRefed<WorkerRunnable>&& aRunnable)
|
2013-10-23 17:16:49 +04:00
|
|
|
{
|
2015-07-10 06:21:46 +03:00
|
|
|
return DispatchPrivate(Move(aRunnable), nullptr);
|
2013-10-23 17:16:49 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2015-07-10 06:21:46 +03:00
|
|
|
DispatchControlRunnable(already_AddRefed<WorkerControlRunnable>&& aWorkerControlRunnable);
|
2013-10-23 17:16:49 +04:00
|
|
|
|
2015-03-04 17:11:32 +03:00
|
|
|
nsresult
|
2015-07-10 06:21:46 +03:00
|
|
|
DispatchDebuggerRunnable(already_AddRefed<WorkerRunnable>&& aDebuggerRunnable);
|
2015-03-04 17:11:32 +03:00
|
|
|
|
2013-10-23 17:16:49 +04:00
|
|
|
already_AddRefed<WorkerRunnable>
|
2015-07-10 06:21:46 +03:00
|
|
|
MaybeWrapAsWorkerRunnable(already_AddRefed<nsIRunnable>&& aRunnable);
|
2013-10-23 17:16:49 +04:00
|
|
|
|
|
|
|
already_AddRefed<nsIEventTarget>
|
|
|
|
GetEventTarget();
|
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
// May be called on any thread...
|
|
|
|
bool
|
|
|
|
Start();
|
|
|
|
|
|
|
|
// Called on the parent thread.
|
|
|
|
bool
|
2011-12-29 22:28:13 +04:00
|
|
|
Notify(JSContext* aCx, Status aStatus)
|
|
|
|
{
|
2012-03-19 18:34:58 +04:00
|
|
|
return NotifyPrivate(aCx, aStatus);
|
2011-12-29 22:28:13 +04:00
|
|
|
}
|
2011-07-17 23:09:13 +04:00
|
|
|
|
|
|
|
bool
|
|
|
|
Cancel(JSContext* aCx)
|
|
|
|
{
|
|
|
|
return Notify(aCx, Canceling);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Kill(JSContext* aCx)
|
|
|
|
{
|
|
|
|
return Notify(aCx, Killing);
|
|
|
|
}
|
|
|
|
|
2015-04-01 12:00:19 +03:00
|
|
|
// We can assume that an nsPIDOMWindow will be available for Freeze, Thaw
|
|
|
|
// as these are only used for globals going in and out of the bfcache.
|
2013-06-05 18:04:23 +04:00
|
|
|
bool
|
2015-04-01 12:00:19 +03:00
|
|
|
Freeze(JSContext* aCx, nsPIDOMWindow* aWindow);
|
2011-07-17 23:09:13 +04:00
|
|
|
|
2013-06-06 21:28:47 +04:00
|
|
|
bool
|
2015-04-01 12:00:19 +03:00
|
|
|
Thaw(JSContext* aCx, nsPIDOMWindow* aWindow);
|
2013-06-06 21:28:47 +04:00
|
|
|
|
2015-10-07 13:20:59 +03:00
|
|
|
void
|
|
|
|
Suspend();
|
|
|
|
|
|
|
|
void
|
|
|
|
Resume();
|
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
bool
|
|
|
|
Terminate(JSContext* aCx)
|
|
|
|
{
|
2012-03-31 08:42:20 +04:00
|
|
|
AssertIsOnParentThread();
|
2012-03-19 18:34:58 +04:00
|
|
|
return TerminatePrivate(aCx);
|
2011-07-17 23:09:13 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2015-04-15 05:35:01 +03:00
|
|
|
Close();
|
2011-07-17 23:09:13 +04:00
|
|
|
|
|
|
|
bool
|
|
|
|
ModifyBusyCount(JSContext* aCx, bool aIncrease);
|
|
|
|
|
2015-02-21 18:09:17 +03:00
|
|
|
void
|
|
|
|
ForgetOverridenLoadGroup(nsCOMPtr<nsILoadGroup>& aLoadGroupOut);
|
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
void
|
|
|
|
ForgetMainThreadObjects(nsTArray<nsCOMPtr<nsISupports> >& aDoomed);
|
|
|
|
|
2013-11-05 18:16:24 +04:00
|
|
|
void
|
2013-05-04 11:53:00 +04:00
|
|
|
PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
2015-10-01 02:11:03 +03:00
|
|
|
const Optional<Sequence<JS::Value>>& aTransferable,
|
|
|
|
ErrorResult& aRv);
|
2013-06-05 18:04:23 +04:00
|
|
|
|
2015-03-16 23:23:42 +03:00
|
|
|
void
|
|
|
|
PostMessageToServiceWorker(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
|
|
|
const Optional<Sequence<JS::Value>>& aTransferable,
|
2015-10-01 02:11:03 +03:00
|
|
|
UniquePtr<ServiceWorkerClientInfo>&& aClientInfo,
|
2015-03-16 23:23:42 +03:00
|
|
|
ErrorResult& aRv);
|
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
void
|
2014-07-30 08:00:37 +04:00
|
|
|
UpdateRuntimeOptions(JSContext* aCx,
|
|
|
|
const JS::RuntimeOptions& aRuntimeOptions);
|
2011-07-17 23:09:13 +04:00
|
|
|
|
2014-09-05 18:26:34 +04:00
|
|
|
void
|
|
|
|
UpdateLanguages(JSContext* aCx, const nsTArray<nsString>& aLanguages);
|
|
|
|
|
2013-11-24 23:27:15 +04:00
|
|
|
void
|
|
|
|
UpdatePreference(JSContext* aCx, WorkerPreference aPref, bool aValue);
|
|
|
|
|
2012-01-04 23:11:32 +04:00
|
|
|
void
|
2013-05-17 02:49:43 +04:00
|
|
|
UpdateJSWorkerMemoryParameter(JSContext* aCx, JSGCParamKey key,
|
|
|
|
uint32_t value);
|
2012-01-04 23:11:32 +04:00
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
#ifdef JS_GC_ZEAL
|
|
|
|
void
|
2013-05-17 02:49:43 +04:00
|
|
|
UpdateGCZeal(JSContext* aCx, uint8_t aGCZeal, uint32_t aFrequency);
|
2011-07-17 23:09:13 +04:00
|
|
|
#endif
|
|
|
|
|
2012-01-18 00:05:25 +04:00
|
|
|
void
|
|
|
|
GarbageCollect(JSContext* aCx, bool aShrinking);
|
|
|
|
|
2013-12-03 08:07:02 +04:00
|
|
|
void
|
|
|
|
CycleCollect(JSContext* aCx, bool aDummy);
|
|
|
|
|
2013-11-20 03:08:50 +04:00
|
|
|
void
|
|
|
|
OfflineStatusChangeEvent(JSContext* aCx, bool aIsOffline);
|
|
|
|
|
2013-06-05 18:04:23 +04:00
|
|
|
bool
|
2015-09-16 06:27:56 +03:00
|
|
|
RegisterSharedWorker(JSContext* aCx, SharedWorker* aSharedWorker,
|
|
|
|
MessagePort* aPort);
|
2013-06-05 18:04:23 +04:00
|
|
|
|
|
|
|
void
|
|
|
|
BroadcastErrorToSharedWorkers(JSContext* aCx,
|
|
|
|
const nsAString& aMessage,
|
|
|
|
const nsAString& aFilename,
|
|
|
|
const nsAString& aLine,
|
|
|
|
uint32_t aLineNumber,
|
|
|
|
uint32_t aColumnNumber,
|
|
|
|
uint32_t aFlags);
|
|
|
|
|
|
|
|
void
|
|
|
|
WorkerScriptLoaded();
|
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
void
|
2013-10-23 17:16:49 +04:00
|
|
|
QueueRunnable(nsIRunnable* aRunnable)
|
2011-07-17 23:09:13 +04:00
|
|
|
{
|
|
|
|
AssertIsOnMainThread();
|
|
|
|
mQueuedRunnables.AppendElement(aRunnable);
|
|
|
|
}
|
|
|
|
|
|
|
|
WorkerPrivate*
|
|
|
|
GetParent() const
|
|
|
|
{
|
|
|
|
return mParent;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2015-04-01 12:00:19 +03:00
|
|
|
IsFrozen() const
|
2011-07-17 23:09:13 +04:00
|
|
|
{
|
|
|
|
AssertIsOnParentThread();
|
2015-04-01 12:00:19 +03:00
|
|
|
return mParentFrozen;
|
2011-07-17 23:09:13 +04:00
|
|
|
}
|
|
|
|
|
2015-10-07 13:20:59 +03:00
|
|
|
bool
|
|
|
|
IsSuspended() const
|
|
|
|
{
|
|
|
|
AssertIsOnParentThread();
|
|
|
|
return mParentSuspended;
|
|
|
|
}
|
|
|
|
|
2012-03-31 08:42:20 +04:00
|
|
|
bool
|
|
|
|
IsAcceptingEvents()
|
|
|
|
{
|
|
|
|
AssertIsOnParentThread();
|
2013-10-23 17:16:49 +04:00
|
|
|
|
|
|
|
MutexAutoLock lock(mMutex);
|
|
|
|
return mParentStatus < Terminating;
|
2013-02-08 15:50:00 +04:00
|
|
|
}
|
2012-03-31 08:42:20 +04:00
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
Status
|
|
|
|
ParentStatus() const
|
|
|
|
{
|
|
|
|
mMutex.AssertCurrentThreadOwns();
|
|
|
|
return mParentStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
JSContext*
|
|
|
|
ParentJSContext() const;
|
|
|
|
|
|
|
|
nsIScriptContext*
|
|
|
|
GetScriptContext() const
|
|
|
|
{
|
|
|
|
AssertIsOnMainThread();
|
2013-06-05 18:04:23 +04:00
|
|
|
return mLoadInfo.mScriptContext;
|
2011-07-17 23:09:13 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
const nsString&
|
|
|
|
ScriptURL() const
|
|
|
|
{
|
|
|
|
return mScriptURL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const nsCString&
|
|
|
|
Domain() const
|
|
|
|
{
|
2013-06-05 18:04:23 +04:00
|
|
|
return mLoadInfo.mDomain;
|
2011-07-17 23:09:13 +04:00
|
|
|
}
|
|
|
|
|
2014-12-17 09:26:15 +03:00
|
|
|
bool
|
|
|
|
IsFromWindow() const
|
|
|
|
{
|
|
|
|
return mLoadInfo.mFromWindow;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
WindowID() const
|
|
|
|
{
|
|
|
|
return mLoadInfo.mWindowID;
|
|
|
|
}
|
|
|
|
|
2015-05-14 22:41:42 +03:00
|
|
|
uint64_t
|
|
|
|
ServiceWorkerID() const
|
|
|
|
{
|
|
|
|
return mLoadInfo.mServiceWorkerID;
|
|
|
|
}
|
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
nsIURI*
|
|
|
|
GetBaseURI() const
|
|
|
|
{
|
|
|
|
AssertIsOnMainThread();
|
2013-06-05 18:04:23 +04:00
|
|
|
return mLoadInfo.mBaseURI;
|
2011-07-17 23:09:13 +04:00
|
|
|
}
|
|
|
|
|
2011-11-04 20:32:17 +04:00
|
|
|
void
|
2011-07-17 23:09:13 +04:00
|
|
|
SetBaseURI(nsIURI* aBaseURI);
|
|
|
|
|
|
|
|
nsIURI*
|
2013-06-05 18:04:23 +04:00
|
|
|
GetResolvedScriptURI() const
|
2011-07-17 23:09:13 +04:00
|
|
|
{
|
|
|
|
AssertIsOnMainThread();
|
2013-06-05 18:04:23 +04:00
|
|
|
return mLoadInfo.mResolvedScriptURI;
|
2011-07-17 23:09:13 +04:00
|
|
|
}
|
|
|
|
|
2015-03-19 21:41:42 +03:00
|
|
|
const nsString&
|
|
|
|
ServiceWorkerCacheName() const
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(IsServiceWorker());
|
|
|
|
AssertIsOnMainThread();
|
2015-03-20 02:39:01 +03:00
|
|
|
return mLoadInfo.mServiceWorkerCacheName;
|
2015-03-19 21:41:42 +03:00
|
|
|
}
|
2015-03-20 02:39:01 +03:00
|
|
|
|
2015-05-25 21:21:05 +03:00
|
|
|
const ChannelInfo&
|
|
|
|
GetChannelInfo() const
|
2015-04-24 01:59:52 +03:00
|
|
|
{
|
2015-05-25 21:21:05 +03:00
|
|
|
return mLoadInfo.mChannelInfo;
|
2015-04-24 01:59:52 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2015-05-25 21:21:05 +03:00
|
|
|
SetChannelInfo(const ChannelInfo& aChannelInfo)
|
2015-04-24 01:59:52 +03:00
|
|
|
{
|
|
|
|
AssertIsOnMainThread();
|
2015-05-25 21:21:05 +03:00
|
|
|
MOZ_ASSERT(!mLoadInfo.mChannelInfo.IsInitialized());
|
|
|
|
MOZ_ASSERT(aChannelInfo.IsInitialized());
|
|
|
|
mLoadInfo.mChannelInfo = aChannelInfo;
|
2015-04-24 01:59:52 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2015-05-25 21:21:05 +03:00
|
|
|
InitChannelInfo(nsIChannel* aChannel)
|
|
|
|
{
|
|
|
|
mLoadInfo.mChannelInfo.InitFromChannel(aChannel);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
InitChannelInfo(const ChannelInfo& aChannelInfo)
|
|
|
|
{
|
|
|
|
mLoadInfo.mChannelInfo = aChannelInfo;
|
|
|
|
}
|
2015-04-24 01:59:52 +03:00
|
|
|
|
2015-03-20 02:39:01 +03:00
|
|
|
// This is used to handle importScripts(). When the worker is first loaded
|
|
|
|
// and executed, it happens in a sync loop. At this point it sets
|
|
|
|
// mLoadingWorkerScript to true. importScripts() calls that occur during the
|
|
|
|
// execution run in nested sync loops and so this continues to return true,
|
|
|
|
// leading to these scripts being cached offline.
|
|
|
|
// mLoadingWorkerScript is set to false when the top level loop ends.
|
|
|
|
// importScripts() in function calls or event handlers are always fetched
|
|
|
|
// from the network.
|
|
|
|
bool
|
|
|
|
LoadScriptAsPartOfLoadingServiceWorkerScript()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(IsServiceWorker());
|
|
|
|
return mLoadingWorkerScript;
|
|
|
|
}
|
|
|
|
|
2015-03-19 21:41:42 +03:00
|
|
|
void
|
|
|
|
SetLoadingWorkerScript(bool aLoadingWorkerScript)
|
|
|
|
{
|
|
|
|
// any thread
|
|
|
|
MOZ_ASSERT(IsServiceWorker());
|
|
|
|
mLoadingWorkerScript = aLoadingWorkerScript;
|
|
|
|
}
|
|
|
|
|
2014-05-06 13:50:12 +04:00
|
|
|
TimeStamp CreationTimeStamp() const
|
|
|
|
{
|
|
|
|
return mCreationTimeStamp;
|
|
|
|
}
|
|
|
|
|
2015-11-19 23:32:49 +03:00
|
|
|
DOMHighResTimeStamp CreationTime() const
|
2015-05-25 19:53:07 +03:00
|
|
|
{
|
|
|
|
return mCreationTimeHighRes;
|
|
|
|
}
|
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
nsIPrincipal*
|
|
|
|
GetPrincipal() const
|
|
|
|
{
|
|
|
|
AssertIsOnMainThread();
|
2013-06-05 18:04:23 +04:00
|
|
|
return mLoadInfo.mPrincipal;
|
2011-07-17 23:09:13 +04:00
|
|
|
}
|
|
|
|
|
2014-12-12 19:06:00 +03:00
|
|
|
nsILoadGroup*
|
|
|
|
GetLoadGroup() const
|
|
|
|
{
|
|
|
|
AssertIsOnMainThread();
|
|
|
|
return mLoadInfo.mLoadGroup;
|
|
|
|
}
|
|
|
|
|
2013-12-03 23:31:30 +04:00
|
|
|
// This method allows the principal to be retrieved off the main thread.
|
|
|
|
// Principals are main-thread objects so the caller must ensure that all
|
|
|
|
// access occurs on the main thread.
|
|
|
|
nsIPrincipal*
|
|
|
|
GetPrincipalDontAssertMainThread() const
|
|
|
|
{
|
|
|
|
return mLoadInfo.mPrincipal;
|
|
|
|
}
|
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
void
|
2014-12-12 19:06:00 +03:00
|
|
|
SetPrincipal(nsIPrincipal* aPrincipal, nsILoadGroup* aLoadGroup);
|
2011-08-16 07:40:38 +04:00
|
|
|
|
|
|
|
bool
|
|
|
|
UsesSystemPrincipal() const
|
2011-07-17 23:09:13 +04:00
|
|
|
{
|
2013-06-05 18:04:23 +04:00
|
|
|
return mLoadInfo.mPrincipalIsSystem;
|
2011-07-17 23:09:13 +04:00
|
|
|
}
|
|
|
|
|
2014-02-05 22:38:16 +04:00
|
|
|
bool
|
|
|
|
IsInPrivilegedApp() const
|
|
|
|
{
|
|
|
|
return mLoadInfo.mIsInPrivilegedApp;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
IsInCertifiedApp() const
|
|
|
|
{
|
|
|
|
return mLoadInfo.mIsInCertifiedApp;
|
|
|
|
}
|
|
|
|
|
2014-12-17 09:26:15 +03:00
|
|
|
const PrincipalInfo&
|
|
|
|
GetPrincipalInfo() const
|
|
|
|
{
|
|
|
|
return *mLoadInfo.mPrincipalInfo;
|
|
|
|
}
|
|
|
|
|
2013-06-05 18:04:23 +04:00
|
|
|
already_AddRefed<nsIChannel>
|
|
|
|
ForgetWorkerChannel()
|
2013-03-08 02:27:21 +04:00
|
|
|
{
|
|
|
|
AssertIsOnMainThread();
|
2013-06-05 18:04:23 +04:00
|
|
|
return mLoadInfo.mChannel.forget();
|
2013-03-08 02:27:21 +04:00
|
|
|
}
|
|
|
|
|
2015-04-07 19:19:19 +03:00
|
|
|
nsIDocument* GetDocument() const;
|
2011-07-17 23:09:13 +04:00
|
|
|
|
|
|
|
nsPIDOMWindow*
|
|
|
|
GetWindow()
|
|
|
|
{
|
|
|
|
AssertIsOnMainThread();
|
2013-06-05 18:04:23 +04:00
|
|
|
return mLoadInfo.mWindow;
|
2011-07-17 23:09:13 +04:00
|
|
|
}
|
|
|
|
|
2012-09-15 22:51:55 +04:00
|
|
|
nsIContentSecurityPolicy*
|
|
|
|
GetCSP() const
|
|
|
|
{
|
|
|
|
AssertIsOnMainThread();
|
2013-06-05 18:04:23 +04:00
|
|
|
return mLoadInfo.mCSP;
|
2012-09-15 22:51:55 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SetCSP(nsIContentSecurityPolicy* aCSP)
|
|
|
|
{
|
|
|
|
AssertIsOnMainThread();
|
2013-06-05 18:04:23 +04:00
|
|
|
mLoadInfo.mCSP = aCSP;
|
2012-09-15 22:51:55 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
IsEvalAllowed() const
|
|
|
|
{
|
2013-06-05 18:04:23 +04:00
|
|
|
return mLoadInfo.mEvalAllowed;
|
2012-09-15 22:51:55 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SetEvalAllowed(bool aEvalAllowed)
|
|
|
|
{
|
2013-06-05 18:04:23 +04:00
|
|
|
mLoadInfo.mEvalAllowed = aEvalAllowed;
|
2012-09-15 22:51:55 +04:00
|
|
|
}
|
|
|
|
|
2012-10-16 00:54:58 +04:00
|
|
|
bool
|
|
|
|
GetReportCSPViolations() const
|
|
|
|
{
|
2013-06-05 18:04:23 +04:00
|
|
|
return mLoadInfo.mReportCSPViolations;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
XHRParamsAllowed() const
|
|
|
|
{
|
|
|
|
return mLoadInfo.mXHRParamsAllowed;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
SetXHRParamsAllowed(bool aAllowed)
|
|
|
|
{
|
|
|
|
mLoadInfo.mXHRParamsAllowed = aAllowed;
|
2012-10-16 00:54:58 +04:00
|
|
|
}
|
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
LocationInfo&
|
|
|
|
GetLocationInfo()
|
|
|
|
{
|
|
|
|
return mLocationInfo;
|
|
|
|
}
|
|
|
|
|
2013-05-17 02:49:43 +04:00
|
|
|
void
|
|
|
|
CopyJSSettings(JSSettings& aSettings)
|
2011-07-17 23:09:13 +04:00
|
|
|
{
|
2013-05-17 02:49:43 +04:00
|
|
|
mozilla::MutexAutoLock lock(mMutex);
|
|
|
|
aSettings = mJSSettings;
|
2011-07-17 23:09:13 +04:00
|
|
|
}
|
|
|
|
|
2013-12-10 15:43:16 +04:00
|
|
|
void
|
|
|
|
CopyJSCompartmentOptions(JS::CompartmentOptions& aOptions)
|
|
|
|
{
|
|
|
|
mozilla::MutexAutoLock lock(mMutex);
|
|
|
|
aOptions = IsChromeWorker() ? mJSSettings.chrome.compartmentOptions
|
|
|
|
: mJSSettings.content.compartmentOptions;
|
|
|
|
}
|
|
|
|
|
2013-10-31 03:40:16 +04:00
|
|
|
// The ability to be a chrome worker is orthogonal to the type of
|
2014-05-12 20:11:15 +04:00
|
|
|
// worker [Dedicated|Shared|Service].
|
2011-07-17 23:09:13 +04:00
|
|
|
bool
|
|
|
|
IsChromeWorker() const
|
|
|
|
{
|
|
|
|
return mIsChromeWorker;
|
|
|
|
}
|
|
|
|
|
2014-10-29 23:11:33 +03:00
|
|
|
WorkerType
|
|
|
|
Type() const
|
|
|
|
{
|
|
|
|
return mWorkerType;
|
|
|
|
}
|
|
|
|
|
2013-10-31 03:40:16 +04:00
|
|
|
bool
|
|
|
|
IsDedicatedWorker() const
|
|
|
|
{
|
|
|
|
return mWorkerType == WorkerTypeDedicated;
|
|
|
|
}
|
|
|
|
|
2013-06-05 18:04:23 +04:00
|
|
|
bool
|
|
|
|
IsSharedWorker() const
|
|
|
|
{
|
2013-10-31 03:40:16 +04:00
|
|
|
return mWorkerType == WorkerTypeShared;
|
2013-06-05 18:04:23 +04:00
|
|
|
}
|
|
|
|
|
2014-05-12 20:11:15 +04:00
|
|
|
bool
|
|
|
|
IsServiceWorker() const
|
|
|
|
{
|
|
|
|
return mWorkerType == WorkerTypeService;
|
|
|
|
}
|
|
|
|
|
2015-06-17 04:21:08 +03:00
|
|
|
nsContentPolicyType
|
|
|
|
ContentPolicyType() const
|
|
|
|
{
|
|
|
|
return ContentPolicyType(mWorkerType);
|
|
|
|
}
|
|
|
|
|
|
|
|
static nsContentPolicyType
|
|
|
|
ContentPolicyType(WorkerType aWorkerType)
|
|
|
|
{
|
|
|
|
switch (aWorkerType) {
|
|
|
|
case WorkerTypeDedicated:
|
|
|
|
return nsIContentPolicy::TYPE_INTERNAL_WORKER;
|
|
|
|
case WorkerTypeShared:
|
|
|
|
return nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER;
|
|
|
|
case WorkerTypeService:
|
2015-09-12 01:48:43 +03:00
|
|
|
return nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER;
|
2015-06-17 04:21:08 +03:00
|
|
|
default:
|
|
|
|
MOZ_ASSERT_UNREACHABLE("Invalid worker type");
|
|
|
|
return nsIContentPolicy::TYPE_INVALID;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-06 18:39:10 +04:00
|
|
|
const nsCString&
|
2015-10-01 02:11:03 +03:00
|
|
|
WorkerName() const
|
2013-06-05 18:04:23 +04:00
|
|
|
{
|
2015-10-01 02:11:03 +03:00
|
|
|
MOZ_ASSERT(IsServiceWorker() || IsSharedWorker());
|
|
|
|
return mWorkerName;
|
2013-06-05 18:04:23 +04:00
|
|
|
}
|
|
|
|
|
2014-12-17 09:26:15 +03:00
|
|
|
bool
|
2015-07-16 00:01:02 +03:00
|
|
|
IsStorageAllowed() const
|
2014-12-17 09:26:15 +03:00
|
|
|
{
|
2015-07-16 00:01:02 +03:00
|
|
|
return mLoadInfo.mStorageAllowed;
|
2014-12-17 09:26:15 +03:00
|
|
|
}
|
|
|
|
|
2015-06-26 21:18:18 +03:00
|
|
|
bool
|
|
|
|
IsInPrivateBrowsing() const
|
|
|
|
{
|
|
|
|
return mLoadInfo.mPrivateBrowsing;
|
|
|
|
}
|
|
|
|
|
2015-06-28 06:19:24 +03:00
|
|
|
// Determine if the SW testing per-window flag is set by devtools
|
|
|
|
bool
|
|
|
|
ServiceWorkersTestingInWindow() const
|
|
|
|
{
|
|
|
|
return mLoadInfo.mServiceWorkersTestingInWindow;
|
|
|
|
}
|
|
|
|
|
2013-06-05 18:04:23 +04:00
|
|
|
void
|
2015-10-18 08:24:48 +03:00
|
|
|
GetAllSharedWorkers(nsTArray<RefPtr<SharedWorker>>& aSharedWorkers);
|
2013-06-05 18:04:23 +04:00
|
|
|
|
|
|
|
void
|
|
|
|
CloseSharedWorkersForWindow(nsPIDOMWindow* aWindow);
|
|
|
|
|
2015-09-23 08:54:29 +03:00
|
|
|
void
|
|
|
|
CloseAllSharedWorkers();
|
|
|
|
|
2015-02-21 18:09:17 +03:00
|
|
|
void
|
|
|
|
UpdateOverridenLoadGroup(nsILoadGroup* aBaseLoadGroup);
|
|
|
|
|
2015-07-15 22:21:40 +03:00
|
|
|
already_AddRefed<nsIRunnable>
|
|
|
|
StealLoadFailedAsyncRunnable()
|
|
|
|
{
|
|
|
|
return mLoadInfo.mLoadFailedAsyncRunnable.forget();
|
|
|
|
}
|
|
|
|
|
2013-11-05 18:16:24 +04:00
|
|
|
IMPL_EVENT_HANDLER(message)
|
|
|
|
IMPL_EVENT_HANDLER(error)
|
2013-06-05 18:04:23 +04:00
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
#ifdef DEBUG
|
|
|
|
void
|
|
|
|
AssertIsOnParentThread() const;
|
|
|
|
|
|
|
|
void
|
|
|
|
AssertInnerWindowIsCorrect() const;
|
|
|
|
#else
|
|
|
|
void
|
|
|
|
AssertIsOnParentThread() const
|
|
|
|
{ }
|
|
|
|
|
|
|
|
void
|
|
|
|
AssertInnerWindowIsCorrect() const
|
|
|
|
{ }
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
2014-10-27 20:00:05 +03:00
|
|
|
class WorkerDebugger : public nsIWorkerDebugger {
|
2015-03-26 22:09:45 +03:00
|
|
|
friend class ::ReportDebuggerErrorRunnable;
|
|
|
|
|
2014-10-27 20:00:05 +03:00
|
|
|
mozilla::Mutex mMutex;
|
|
|
|
mozilla::CondVar mCondVar;
|
|
|
|
|
|
|
|
// Protected by mMutex
|
|
|
|
WorkerPrivate* mWorkerPrivate;
|
|
|
|
bool mIsEnabled;
|
|
|
|
|
2014-10-29 23:11:33 +03:00
|
|
|
// Only touched on the main thread.
|
2015-03-17 13:15:19 +03:00
|
|
|
bool mIsInitialized;
|
2014-10-29 23:11:33 +03:00
|
|
|
nsTArray<nsCOMPtr<nsIWorkerDebuggerListener>> mListeners;
|
|
|
|
|
2014-10-27 20:00:05 +03:00
|
|
|
public:
|
2014-10-11 01:28:35 +04:00
|
|
|
explicit WorkerDebugger(WorkerPrivate* aWorkerPrivate);
|
2014-10-27 20:00:05 +03:00
|
|
|
|
|
|
|
NS_DECL_THREADSAFE_ISUPPORTS
|
|
|
|
NS_DECL_NSIWORKERDEBUGGER
|
|
|
|
|
2015-03-20 14:15:59 +03:00
|
|
|
void
|
|
|
|
AssertIsOnParentThread();
|
|
|
|
|
|
|
|
void
|
|
|
|
WaitIsEnabled(bool aIsEnabled);
|
2014-10-27 20:00:05 +03:00
|
|
|
|
2015-03-20 14:15:59 +03:00
|
|
|
void
|
|
|
|
Enable();
|
2014-10-27 20:00:05 +03:00
|
|
|
|
2015-03-20 14:15:59 +03:00
|
|
|
void
|
|
|
|
Disable();
|
2014-10-27 20:00:05 +03:00
|
|
|
|
2015-03-20 14:15:59 +03:00
|
|
|
void
|
|
|
|
PostMessageToDebugger(const nsAString& aMessage);
|
2014-10-27 20:00:05 +03:00
|
|
|
|
2015-03-26 22:09:45 +03:00
|
|
|
void
|
|
|
|
ReportErrorToDebugger(const nsAString& aFilename, uint32_t aLineno,
|
|
|
|
const nsAString& aMessage);
|
|
|
|
|
2014-10-27 20:00:05 +03:00
|
|
|
private:
|
2015-03-20 14:15:59 +03:00
|
|
|
virtual
|
|
|
|
~WorkerDebugger();
|
2014-10-27 20:00:05 +03:00
|
|
|
|
2015-03-20 14:15:59 +03:00
|
|
|
void
|
|
|
|
NotifyIsEnabled(bool aIsEnabled);
|
|
|
|
|
|
|
|
void
|
|
|
|
PostMessageToDebuggerOnMainThread(const nsAString& aMessage);
|
2015-03-26 22:09:45 +03:00
|
|
|
|
|
|
|
void
|
|
|
|
ReportErrorToDebuggerOnMainThread(const nsAString& aFilename,
|
|
|
|
uint32_t aLineno,
|
|
|
|
const nsAString& aMessage);
|
2014-10-27 20:00:05 +03:00
|
|
|
};
|
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
class WorkerPrivate : public WorkerPrivateParent<WorkerPrivate>
|
|
|
|
{
|
|
|
|
friend class WorkerPrivateParent<WorkerPrivate>;
|
|
|
|
typedef WorkerPrivateParent<WorkerPrivate> ParentType;
|
2013-10-23 17:16:49 +04:00
|
|
|
friend class AutoSyncLoopHolder;
|
2011-07-17 23:09:13 +04:00
|
|
|
|
|
|
|
struct TimeoutInfo;
|
|
|
|
|
2013-10-23 17:16:49 +04:00
|
|
|
class MemoryReporter;
|
|
|
|
friend class MemoryReporter;
|
2011-07-17 23:09:13 +04:00
|
|
|
|
2014-11-17 22:55:37 +03:00
|
|
|
friend class WorkerThread;
|
|
|
|
|
2013-10-23 17:16:49 +04:00
|
|
|
enum GCTimerMode
|
2011-07-17 23:09:13 +04:00
|
|
|
{
|
2013-10-23 17:16:49 +04:00
|
|
|
PeriodicTimer = 0,
|
|
|
|
IdleTimer,
|
|
|
|
NoTimer
|
2011-07-17 23:09:13 +04:00
|
|
|
};
|
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<WorkerDebugger> mDebugger;
|
2014-10-27 20:00:05 +03:00
|
|
|
|
2013-10-23 17:16:49 +04:00
|
|
|
Queue<WorkerControlRunnable*, 4> mControlQueue;
|
2015-03-04 17:11:32 +03:00
|
|
|
Queue<WorkerRunnable*, 4> mDebuggerQueue;
|
2011-07-17 23:09:13 +04:00
|
|
|
|
|
|
|
// Touched on multiple threads, protected with mMutex.
|
|
|
|
JSContext* mJSContext;
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<WorkerCrossThreadDispatcher> mCrossThreadDispatcher;
|
2013-10-23 17:16:49 +04:00
|
|
|
nsTArray<nsCOMPtr<nsIRunnable>> mUndispatchedRunnablesForSyncLoop;
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<WorkerThread> mThread;
|
2014-11-17 22:55:37 +03:00
|
|
|
PRThread* mPRThread;
|
2011-07-17 23:09:13 +04:00
|
|
|
|
|
|
|
// Things touched on worker thread only.
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<WorkerGlobalScope> mScope;
|
|
|
|
RefPtr<WorkerDebuggerGlobalScope> mDebuggerScope;
|
2011-07-17 23:09:13 +04:00
|
|
|
nsTArray<ParentType*> mChildWorkers;
|
2015-04-07 20:31:51 +03:00
|
|
|
nsTObserverArray<WorkerFeature*> mFeatures;
|
2013-10-23 17:16:49 +04:00
|
|
|
nsTArray<nsAutoPtr<TimeoutInfo>> mTimeouts;
|
2015-03-27 09:17:16 +03:00
|
|
|
uint32_t mDebuggerEventLoopLevel;
|
2013-10-23 17:16:49 +04:00
|
|
|
|
|
|
|
struct SyncLoopInfo
|
|
|
|
{
|
2014-09-02 04:49:25 +04:00
|
|
|
explicit SyncLoopInfo(EventTarget* aEventTarget);
|
2013-10-23 17:16:49 +04:00
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<EventTarget> mEventTarget;
|
2013-10-23 17:16:49 +04:00
|
|
|
bool mCompleted;
|
|
|
|
bool mResult;
|
|
|
|
#ifdef DEBUG
|
|
|
|
bool mHasRun;
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
|
|
|
// This is only modified on the worker thread, but in DEBUG builds
|
|
|
|
// AssertValidSyncLoop function iterates it on other threads. Therefore
|
|
|
|
// modifications are done with mMutex held *only* in DEBUG builds.
|
|
|
|
nsTArray<nsAutoPtr<SyncLoopInfo>> mSyncLoopStack;
|
2011-07-17 23:09:13 +04:00
|
|
|
|
|
|
|
nsCOMPtr<nsITimer> mTimer;
|
2013-10-23 17:16:49 +04:00
|
|
|
|
2015-11-18 06:45:43 +03:00
|
|
|
nsCOMPtr<nsITimer> mGCTimer;
|
|
|
|
nsCOMPtr<nsIEventTarget> mPeriodicGCTimerTarget;
|
|
|
|
nsCOMPtr<nsIEventTarget> mIdleGCTimerTarget;
|
2013-10-23 17:16:49 +04:00
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<MemoryReporter> mMemoryReporter;
|
2011-07-17 23:09:13 +04:00
|
|
|
|
2015-07-15 22:21:40 +03:00
|
|
|
// fired on the main thread if the worker script fails to load
|
|
|
|
nsCOMPtr<nsIRunnable> mLoadFailedRunnable;
|
|
|
|
|
2013-10-23 17:16:49 +04:00
|
|
|
TimeStamp mKillTime;
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t mErrorHandlerRecursionCount;
|
|
|
|
uint32_t mNextTimeoutId;
|
2011-07-17 23:09:13 +04:00
|
|
|
Status mStatus;
|
2015-04-01 12:00:19 +03:00
|
|
|
bool mFrozen;
|
2011-07-17 23:09:13 +04:00
|
|
|
bool mTimerRunning;
|
|
|
|
bool mRunningExpiredTimeouts;
|
|
|
|
bool mCloseHandlerStarted;
|
|
|
|
bool mCloseHandlerFinished;
|
2015-09-29 00:34:28 +03:00
|
|
|
bool mPendingEventQueueClearing;
|
2011-09-09 04:03:03 +04:00
|
|
|
bool mMemoryReporterRunning;
|
2012-12-30 22:21:52 +04:00
|
|
|
bool mBlockedForMemoryReporter;
|
2013-10-23 17:16:49 +04:00
|
|
|
bool mCancelAllPendingRunnables;
|
|
|
|
bool mPeriodicGCTimerRunning;
|
2013-12-20 23:03:19 +04:00
|
|
|
bool mIdleGCTimerRunning;
|
2014-05-29 20:33:04 +04:00
|
|
|
bool mWorkerScriptExecutedSuccessfully;
|
2013-11-24 23:27:15 +04:00
|
|
|
bool mPreferences[WORKERPREF_COUNT];
|
2013-11-20 03:08:50 +04:00
|
|
|
bool mOnLine;
|
2013-11-24 23:27:15 +04:00
|
|
|
|
2013-11-05 18:16:24 +04:00
|
|
|
protected:
|
2013-10-14 22:38:54 +04:00
|
|
|
~WorkerPrivate();
|
2013-10-14 15:58:05 +04:00
|
|
|
|
2013-11-05 18:16:24 +04:00
|
|
|
public:
|
|
|
|
static already_AddRefed<WorkerPrivate>
|
|
|
|
Constructor(const GlobalObject& aGlobal, const nsAString& aScriptURL,
|
|
|
|
ErrorResult& aRv);
|
|
|
|
|
2012-03-31 08:42:20 +04:00
|
|
|
static already_AddRefed<WorkerPrivate>
|
2013-11-05 18:16:24 +04:00
|
|
|
Constructor(const GlobalObject& aGlobal, const nsAString& aScriptURL,
|
|
|
|
bool aIsChromeWorker, WorkerType aWorkerType,
|
2014-02-06 18:39:10 +04:00
|
|
|
const nsACString& aSharedWorkerName,
|
2015-02-12 12:50:05 +03:00
|
|
|
WorkerLoadInfo* aLoadInfo, ErrorResult& aRv);
|
2013-11-05 18:16:24 +04:00
|
|
|
|
2014-05-29 20:19:00 +04:00
|
|
|
static already_AddRefed<WorkerPrivate>
|
|
|
|
Constructor(JSContext* aCx, const nsAString& aScriptURL, bool aIsChromeWorker,
|
|
|
|
WorkerType aWorkerType, const nsACString& aSharedWorkerName,
|
2015-02-12 12:50:05 +03:00
|
|
|
WorkerLoadInfo* aLoadInfo, ErrorResult& aRv);
|
2014-05-29 20:19:00 +04:00
|
|
|
|
2013-11-05 18:16:24 +04:00
|
|
|
static bool
|
|
|
|
WorkerAvailable(JSContext* /* unused */, JSObject* /* unused */);
|
2013-06-05 18:04:23 +04:00
|
|
|
|
2015-02-21 18:09:17 +03:00
|
|
|
enum LoadGroupBehavior
|
|
|
|
{
|
|
|
|
InheritLoadGroup,
|
|
|
|
OverrideLoadGroup
|
|
|
|
};
|
|
|
|
|
2013-06-05 18:04:23 +04:00
|
|
|
static nsresult
|
|
|
|
GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow, WorkerPrivate* aParent,
|
|
|
|
const nsAString& aScriptURL, bool aIsChromeWorker,
|
2015-06-17 04:21:08 +03:00
|
|
|
LoadGroupBehavior aLoadGroupBehavior, WorkerType aWorkerType,
|
|
|
|
WorkerLoadInfo* aLoadInfo);
|
2015-02-21 18:09:17 +03:00
|
|
|
|
|
|
|
static void
|
2015-02-12 12:50:05 +03:00
|
|
|
OverrideLoadInfoLoadGroup(WorkerLoadInfo& aLoadInfo);
|
2011-07-17 23:09:13 +04:00
|
|
|
|
2014-10-29 23:11:33 +03:00
|
|
|
WorkerDebugger*
|
|
|
|
Debugger() const
|
|
|
|
{
|
|
|
|
AssertIsOnMainThread();
|
|
|
|
MOZ_ASSERT(mDebugger);
|
|
|
|
return mDebugger;
|
|
|
|
}
|
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
void
|
|
|
|
DoRunLoop(JSContext* aCx);
|
|
|
|
|
|
|
|
bool
|
2014-03-11 01:28:43 +04:00
|
|
|
InterruptCallback(JSContext* aCx);
|
2011-07-17 23:09:13 +04:00
|
|
|
|
2013-10-23 17:16:49 +04:00
|
|
|
nsresult
|
|
|
|
IsOnCurrentThread(bool* aIsOnCurrentThread);
|
2011-07-17 23:09:13 +04:00
|
|
|
|
|
|
|
bool
|
|
|
|
CloseInternal(JSContext* aCx)
|
|
|
|
{
|
|
|
|
AssertIsOnWorkerThread();
|
|
|
|
return NotifyInternal(aCx, Closing);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2015-04-01 12:00:19 +03:00
|
|
|
FreezeInternal(JSContext* aCx);
|
2011-07-17 23:09:13 +04:00
|
|
|
|
|
|
|
bool
|
2015-04-01 12:00:19 +03:00
|
|
|
ThawInternal(JSContext* aCx);
|
2011-07-17 23:09:13 +04:00
|
|
|
|
|
|
|
void
|
2013-11-05 18:16:26 +04:00
|
|
|
TraceTimeouts(const TraceCallbacks& aCallbacks, void* aClosure) const;
|
2011-07-17 23:09:13 +04:00
|
|
|
|
|
|
|
bool
|
|
|
|
ModifyBusyCountFromWorker(JSContext* aCx, bool aIncrease);
|
|
|
|
|
|
|
|
bool
|
|
|
|
AddChildWorker(JSContext* aCx, ParentType* aChildWorker);
|
|
|
|
|
|
|
|
void
|
|
|
|
RemoveChildWorker(JSContext* aCx, ParentType* aChildWorker);
|
|
|
|
|
|
|
|
bool
|
|
|
|
AddFeature(JSContext* aCx, WorkerFeature* aFeature);
|
|
|
|
|
|
|
|
void
|
|
|
|
RemoveFeature(JSContext* aCx, WorkerFeature* aFeature);
|
|
|
|
|
|
|
|
void
|
|
|
|
NotifyFeatures(JSContext* aCx, Status aStatus);
|
|
|
|
|
|
|
|
bool
|
|
|
|
HasActiveFeatures()
|
|
|
|
{
|
|
|
|
return !(mChildWorkers.IsEmpty() && mTimeouts.IsEmpty() &&
|
|
|
|
mFeatures.IsEmpty());
|
|
|
|
}
|
|
|
|
|
2013-11-05 18:16:26 +04:00
|
|
|
void
|
2013-06-05 18:04:23 +04:00
|
|
|
PostMessageToParent(JSContext* aCx,
|
|
|
|
JS::Handle<JS::Value> aMessage,
|
2013-11-05 18:16:26 +04:00
|
|
|
const Optional<Sequence<JS::Value>>& aTransferable,
|
|
|
|
ErrorResult& aRv)
|
2013-06-05 18:04:23 +04:00
|
|
|
{
|
2015-09-16 06:27:56 +03:00
|
|
|
PostMessageToParentInternal(aCx, aMessage, aTransferable, aRv);
|
2013-06-05 18:04:23 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
PostMessageToParentMessagePort(
|
|
|
|
JSContext* aCx,
|
2013-11-11 12:04:41 +04:00
|
|
|
JS::Handle<JS::Value> aMessage,
|
2013-06-05 18:04:23 +04:00
|
|
|
const Optional<Sequence<JS::Value>>& aTransferable,
|
|
|
|
ErrorResult& aRv);
|
2011-07-17 23:09:13 +04:00
|
|
|
|
2015-03-27 09:17:16 +03:00
|
|
|
void
|
|
|
|
EnterDebuggerEventLoop();
|
|
|
|
|
|
|
|
void
|
|
|
|
LeaveDebuggerEventLoop();
|
|
|
|
|
2015-03-20 14:15:59 +03:00
|
|
|
void
|
|
|
|
PostMessageToDebugger(const nsAString& aMessage);
|
|
|
|
|
2015-03-30 14:54:38 +03:00
|
|
|
void
|
|
|
|
SetDebuggerImmediate(JSContext* aCx, Function& aHandler, ErrorResult& aRv);
|
|
|
|
|
2015-03-26 22:09:45 +03:00
|
|
|
void
|
|
|
|
ReportErrorToDebugger(const nsAString& aFilename, uint32_t aLineno,
|
|
|
|
const nsAString& aMessage);
|
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
bool
|
|
|
|
NotifyInternal(JSContext* aCx, Status aStatus);
|
|
|
|
|
|
|
|
void
|
|
|
|
ReportError(JSContext* aCx, const char* aMessage, JSErrorReport* aReport);
|
|
|
|
|
2013-11-05 18:16:26 +04:00
|
|
|
int32_t
|
|
|
|
SetTimeout(JSContext* aCx,
|
|
|
|
Function* aHandler,
|
|
|
|
const nsAString& aStringHandler,
|
|
|
|
int32_t aTimeout,
|
|
|
|
const Sequence<JS::Value>& aArguments,
|
|
|
|
bool aIsInterval,
|
|
|
|
ErrorResult& aRv);
|
2011-07-17 23:09:13 +04:00
|
|
|
|
2013-11-05 18:16:26 +04:00
|
|
|
void
|
|
|
|
ClearTimeout(int32_t aId);
|
2011-07-17 23:09:13 +04:00
|
|
|
|
|
|
|
bool
|
|
|
|
RunExpiredTimeouts(JSContext* aCx);
|
|
|
|
|
|
|
|
bool
|
|
|
|
RescheduleTimeoutTimer(JSContext* aCx);
|
|
|
|
|
|
|
|
void
|
|
|
|
CloseHandlerStarted()
|
|
|
|
{
|
|
|
|
AssertIsOnWorkerThread();
|
|
|
|
mCloseHandlerStarted = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CloseHandlerFinished()
|
|
|
|
{
|
|
|
|
AssertIsOnWorkerThread();
|
|
|
|
mCloseHandlerFinished = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-07-30 08:00:37 +04:00
|
|
|
UpdateRuntimeOptionsInternal(JSContext* aCx, const JS::RuntimeOptions& aRuntimeOptions);
|
2011-07-17 23:09:13 +04:00
|
|
|
|
2014-09-05 18:26:34 +04:00
|
|
|
void
|
|
|
|
UpdateLanguagesInternal(JSContext* aCx, const nsTArray<nsString>& aLanguages);
|
|
|
|
|
2013-11-24 23:27:15 +04:00
|
|
|
void
|
|
|
|
UpdatePreferenceInternal(JSContext* aCx, WorkerPreference aPref, bool aValue);
|
|
|
|
|
2012-01-04 23:11:32 +04:00
|
|
|
void
|
2013-01-11 02:50:40 +04:00
|
|
|
UpdateJSWorkerMemoryParameterInternal(JSContext* aCx, JSGCParamKey key, uint32_t aValue);
|
2012-01-04 23:11:32 +04:00
|
|
|
|
2014-03-05 03:09:23 +04:00
|
|
|
enum WorkerRanOrNot {
|
|
|
|
WorkerNeverRan = 0,
|
|
|
|
WorkerRan
|
|
|
|
};
|
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
void
|
2014-03-05 03:09:23 +04:00
|
|
|
ScheduleDeletion(WorkerRanOrNot aRanOrNot);
|
2011-07-17 23:09:13 +04:00
|
|
|
|
2011-08-07 05:03:46 +04:00
|
|
|
bool
|
2014-05-21 10:06:54 +04:00
|
|
|
BlockAndCollectRuntimeStats(JS::RuntimeStats* aRtStats, bool aAnonymize);
|
2011-09-09 04:03:03 +04:00
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
#ifdef JS_GC_ZEAL
|
|
|
|
void
|
2013-05-17 02:49:43 +04:00
|
|
|
UpdateGCZealInternal(JSContext* aCx, uint8_t aGCZeal, uint32_t aFrequency);
|
2011-07-17 23:09:13 +04:00
|
|
|
#endif
|
|
|
|
|
2012-01-18 00:05:25 +04:00
|
|
|
void
|
|
|
|
GarbageCollectInternal(JSContext* aCx, bool aShrinking,
|
|
|
|
bool aCollectChildren);
|
|
|
|
|
2013-12-03 08:07:02 +04:00
|
|
|
void
|
|
|
|
CycleCollectInternal(JSContext* aCx, bool aCollectChildren);
|
|
|
|
|
2013-11-20 03:08:50 +04:00
|
|
|
void
|
|
|
|
OfflineStatusChangeEventInternal(JSContext* aCx, bool aIsOffline);
|
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
JSContext*
|
|
|
|
GetJSContext() const
|
|
|
|
{
|
|
|
|
AssertIsOnWorkerThread();
|
|
|
|
return mJSContext;
|
|
|
|
}
|
|
|
|
|
2013-11-05 18:16:26 +04:00
|
|
|
WorkerGlobalScope*
|
|
|
|
GlobalScope() const
|
|
|
|
{
|
|
|
|
AssertIsOnWorkerThread();
|
|
|
|
return mScope;
|
|
|
|
}
|
|
|
|
|
2015-03-04 02:51:53 +03:00
|
|
|
WorkerDebuggerGlobalScope*
|
|
|
|
DebuggerGlobalScope() const
|
|
|
|
{
|
|
|
|
AssertIsOnWorkerThread();
|
|
|
|
return mDebuggerScope;
|
|
|
|
}
|
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
void
|
2014-11-17 22:55:37 +03:00
|
|
|
SetThread(WorkerThread* aThread);
|
2011-07-17 23:09:13 +04:00
|
|
|
|
|
|
|
void
|
|
|
|
AssertIsOnWorkerThread() const
|
2013-10-23 17:16:49 +04:00
|
|
|
#ifdef DEBUG
|
|
|
|
;
|
|
|
|
#else
|
2011-07-17 23:09:13 +04:00
|
|
|
{ }
|
|
|
|
#endif
|
|
|
|
|
2011-12-05 11:58:27 +04:00
|
|
|
WorkerCrossThreadDispatcher*
|
|
|
|
GetCrossThreadDispatcher();
|
|
|
|
|
2012-12-30 22:21:52 +04:00
|
|
|
// This may block!
|
|
|
|
void
|
|
|
|
BeginCTypesCall();
|
|
|
|
|
|
|
|
// This may block!
|
|
|
|
void
|
|
|
|
EndCTypesCall();
|
|
|
|
|
2013-01-08 16:57:44 +04:00
|
|
|
void
|
|
|
|
BeginCTypesCallback()
|
|
|
|
{
|
|
|
|
// If a callback is beginning then we need to do the exact same thing as
|
|
|
|
// when a ctypes call ends.
|
|
|
|
EndCTypesCall();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
EndCTypesCallback()
|
|
|
|
{
|
|
|
|
// If a callback is ending then we need to do the exact same thing as
|
|
|
|
// when a ctypes call begins.
|
|
|
|
BeginCTypesCall();
|
|
|
|
}
|
|
|
|
|
2013-06-05 18:04:23 +04:00
|
|
|
bool
|
2015-09-16 06:27:56 +03:00
|
|
|
ConnectMessagePort(JSContext* aCx, MessagePortIdentifier& aIdentifier);
|
2013-06-05 18:04:23 +04:00
|
|
|
|
2015-03-04 02:51:53 +03:00
|
|
|
WorkerGlobalScope*
|
|
|
|
GetOrCreateGlobalScope(JSContext* aCx);
|
|
|
|
|
|
|
|
WorkerDebuggerGlobalScope*
|
|
|
|
CreateDebuggerGlobalScope(JSContext* aCx);
|
2013-11-05 18:16:26 +04:00
|
|
|
|
|
|
|
bool
|
|
|
|
RegisterBindings(JSContext* aCx, JS::Handle<JSObject*> aGlobal);
|
|
|
|
|
2015-10-24 19:06:57 +03:00
|
|
|
#define WORKER_SIMPLE_PREF(name, getter, NAME) \
|
|
|
|
bool \
|
|
|
|
getter() const \
|
|
|
|
{ \
|
|
|
|
AssertIsOnWorkerThread(); \
|
|
|
|
return mPreferences[WORKERPREF_##NAME]; \
|
|
|
|
}
|
|
|
|
#define WORKER_PREF(name, callback)
|
|
|
|
#include "WorkerPrefs.h"
|
|
|
|
#undef WORKER_SIMPLE_PREF
|
|
|
|
#undef WORKER_PREF
|
2015-10-12 06:21:04 +03:00
|
|
|
|
2015-07-28 00:57:34 +03:00
|
|
|
bool
|
2013-11-20 03:08:50 +04:00
|
|
|
OnLine() const
|
|
|
|
{
|
|
|
|
AssertIsOnWorkerThread();
|
|
|
|
return mOnLine;
|
|
|
|
}
|
|
|
|
|
2013-10-23 17:16:49 +04:00
|
|
|
void
|
|
|
|
StopSyncLoop(nsIEventTarget* aSyncLoopTarget, bool aResult);
|
|
|
|
|
|
|
|
bool
|
|
|
|
AllPendingRunnablesShouldBeCanceled() const
|
|
|
|
{
|
|
|
|
return mCancelAllPendingRunnables;
|
|
|
|
}
|
|
|
|
|
2015-04-09 01:20:59 +03:00
|
|
|
void
|
|
|
|
ClearMainEventQueue(WorkerRanOrNot aRanOrNot);
|
|
|
|
|
2013-10-23 17:16:49 +04:00
|
|
|
void
|
Bug 1179909: Refactor stable state handling. r=smaug
This is motivated by three separate but related problems:
1. Our concept of recursion depth is broken for things that run from AfterProcessNextEvent observers (e.g. Promises). We decrement the recursionDepth counter before firing observers, so a Promise callback running at the lowest event loop depth has a recursion depth of 0 (whereas a regular nsIRunnable would be 1). This is a problem because it's impossible to distinguish a Promise running after a sync XHR's onreadystatechange handler from a top-level event (since the former runs with depth 2 - 1 = 1, and the latter runs with just 1).
2. The nsIThreadObserver mechanism that is used by a lot of code to run "after" the current event is a poor fit for anything that runs script. First, the order the observers fire in is the order they were added, not anything fixed by spec. Additionally, running script can cause the event loop to spin, which is a big source of pain here (bholley has some nasty bug caused by this).
3. We run Promises from different points in the code for workers and main thread. The latter runs from XPConnect's nsIThreadObserver callbacks, while the former runs from a hardcoded call to run Promises in the worker event loop. What workers do is particularly problematic because it means we can't get the right recursion depth no matter what we do to nsThread.
The solve this, this patch does the following:
1. Consolidate some handling of microtasks and all handling of stable state from appshell and WorkerPrivate into CycleCollectedJSRuntime.
2. Make the recursionDepth counter only available to CycleCollectedJSRuntime (and its consumers) and remove it from the nsIThreadInternal and nsIThreadObserver APIs.
3. Adjust the recursionDepth counter so that microtasks run with the recursionDepth of the task they are associated with.
4. Introduce the concept of metastable state to replace appshell's RunBeforeNextEvent. Metastable state is reached after every microtask or task is completed. This provides the semantics that bent and I want for IndexedDB, where transactions autocommit at the end of a microtask and do not "spill" from one microtask into a subsequent microtask. This differs from appshell's RunBeforeNextEvent in two ways:
a) It fires between microtasks, which was the motivation for starting this.
b) It no longer ensures that we're at the same event loop depth in the native event queue. bent decided we don't care about this.
5. Reorder stable state to happen after microtasks such as Promises, per HTML. Right now we call the regular thread observers, including appshell, before the main thread observer (XPConnect), so stable state tasks happen before microtasks.
2015-08-11 16:10:46 +03:00
|
|
|
OnProcessNextEvent();
|
2013-10-23 17:16:49 +04:00
|
|
|
|
|
|
|
void
|
Bug 1179909: Refactor stable state handling. r=smaug
This is motivated by three separate but related problems:
1. Our concept of recursion depth is broken for things that run from AfterProcessNextEvent observers (e.g. Promises). We decrement the recursionDepth counter before firing observers, so a Promise callback running at the lowest event loop depth has a recursion depth of 0 (whereas a regular nsIRunnable would be 1). This is a problem because it's impossible to distinguish a Promise running after a sync XHR's onreadystatechange handler from a top-level event (since the former runs with depth 2 - 1 = 1, and the latter runs with just 1).
2. The nsIThreadObserver mechanism that is used by a lot of code to run "after" the current event is a poor fit for anything that runs script. First, the order the observers fire in is the order they were added, not anything fixed by spec. Additionally, running script can cause the event loop to spin, which is a big source of pain here (bholley has some nasty bug caused by this).
3. We run Promises from different points in the code for workers and main thread. The latter runs from XPConnect's nsIThreadObserver callbacks, while the former runs from a hardcoded call to run Promises in the worker event loop. What workers do is particularly problematic because it means we can't get the right recursion depth no matter what we do to nsThread.
The solve this, this patch does the following:
1. Consolidate some handling of microtasks and all handling of stable state from appshell and WorkerPrivate into CycleCollectedJSRuntime.
2. Make the recursionDepth counter only available to CycleCollectedJSRuntime (and its consumers) and remove it from the nsIThreadInternal and nsIThreadObserver APIs.
3. Adjust the recursionDepth counter so that microtasks run with the recursionDepth of the task they are associated with.
4. Introduce the concept of metastable state to replace appshell's RunBeforeNextEvent. Metastable state is reached after every microtask or task is completed. This provides the semantics that bent and I want for IndexedDB, where transactions autocommit at the end of a microtask and do not "spill" from one microtask into a subsequent microtask. This differs from appshell's RunBeforeNextEvent in two ways:
a) It fires between microtasks, which was the motivation for starting this.
b) It no longer ensures that we're at the same event loop depth in the native event queue. bent decided we don't care about this.
5. Reorder stable state to happen after microtasks such as Promises, per HTML. Right now we call the regular thread observers, including appshell, before the main thread observer (XPConnect), so stable state tasks happen before microtasks.
2015-08-11 16:10:46 +03:00
|
|
|
AfterProcessNextEvent();
|
2013-10-23 17:16:49 +04:00
|
|
|
|
|
|
|
void
|
|
|
|
AssertValidSyncLoop(nsIEventTarget* aSyncLoopTarget)
|
|
|
|
#ifdef DEBUG
|
|
|
|
;
|
|
|
|
#else
|
|
|
|
{ }
|
|
|
|
#endif
|
|
|
|
|
2014-05-29 20:33:04 +04:00
|
|
|
void
|
|
|
|
SetWorkerScriptExecutedSuccessfully()
|
|
|
|
{
|
|
|
|
AssertIsOnWorkerThread();
|
|
|
|
// Should only be called once!
|
|
|
|
MOZ_ASSERT(!mWorkerScriptExecutedSuccessfully);
|
|
|
|
mWorkerScriptExecutedSuccessfully = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Only valid after CompileScriptRunnable has finished running!
|
|
|
|
bool
|
|
|
|
WorkerScriptExecutedSuccessfully() const
|
|
|
|
{
|
|
|
|
AssertIsOnWorkerThread();
|
|
|
|
return mWorkerScriptExecutedSuccessfully;
|
|
|
|
}
|
|
|
|
|
2015-07-15 22:21:40 +03:00
|
|
|
void
|
|
|
|
MaybeDispatchLoadFailedRunnable();
|
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
private:
|
2013-11-05 18:16:24 +04:00
|
|
|
WorkerPrivate(JSContext* aCx, WorkerPrivate* aParent,
|
|
|
|
const nsAString& aScriptURL, bool aIsChromeWorker,
|
2014-02-06 18:39:10 +04:00
|
|
|
WorkerType aWorkerType, const nsACString& aSharedWorkerName,
|
2015-02-12 12:50:05 +03:00
|
|
|
WorkerLoadInfo& aLoadInfo);
|
2012-09-15 22:51:55 +04:00
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
bool
|
|
|
|
MayContinueRunning()
|
|
|
|
{
|
|
|
|
AssertIsOnWorkerThread();
|
|
|
|
|
|
|
|
Status status;
|
|
|
|
{
|
2013-10-23 17:16:49 +04:00
|
|
|
MutexAutoLock lock(mMutex);
|
2011-07-17 23:09:13 +04:00
|
|
|
status = mStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (status >= Killing) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (status >= Running) {
|
|
|
|
return mKillTime.IsNull() || RemainingRunTimeMS() > 0;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t
|
2011-07-17 23:09:13 +04:00
|
|
|
RemainingRunTimeMS() const;
|
|
|
|
|
|
|
|
void
|
|
|
|
CancelAllTimeouts(JSContext* aCx);
|
|
|
|
|
|
|
|
bool
|
|
|
|
ScheduleKillCloseEventRunnable(JSContext* aCx);
|
|
|
|
|
2013-10-23 17:16:49 +04:00
|
|
|
bool
|
|
|
|
ProcessAllControlRunnables()
|
2011-07-17 23:09:13 +04:00
|
|
|
{
|
2013-10-23 17:16:49 +04:00
|
|
|
MutexAutoLock lock(mMutex);
|
|
|
|
return ProcessAllControlRunnablesLocked();
|
2011-07-17 23:09:13 +04:00
|
|
|
}
|
2011-09-09 04:03:03 +04:00
|
|
|
|
|
|
|
bool
|
2013-10-23 17:16:49 +04:00
|
|
|
ProcessAllControlRunnablesLocked();
|
2012-09-17 04:20:16 +04:00
|
|
|
|
2012-12-30 22:21:52 +04:00
|
|
|
void
|
|
|
|
EnableMemoryReporter();
|
|
|
|
|
|
|
|
void
|
|
|
|
DisableMemoryReporter();
|
|
|
|
|
|
|
|
void
|
|
|
|
WaitForWorkerEvents(PRIntervalTime interval = PR_INTERVAL_NO_TIMEOUT);
|
|
|
|
|
2013-11-05 18:16:26 +04:00
|
|
|
void
|
2013-06-05 18:04:23 +04:00
|
|
|
PostMessageToParentInternal(JSContext* aCx,
|
|
|
|
JS::Handle<JS::Value> aMessage,
|
2013-11-05 18:16:26 +04:00
|
|
|
const Optional<Sequence<JS::Value>>& aTransferable,
|
|
|
|
ErrorResult& aRv);
|
2013-11-24 23:27:15 +04:00
|
|
|
|
|
|
|
void
|
|
|
|
GetAllPreferences(bool aPreferences[WORKERPREF_COUNT]) const
|
|
|
|
{
|
|
|
|
AssertIsOnWorkerThread();
|
|
|
|
memcpy(aPreferences, mPreferences, WORKERPREF_COUNT * sizeof(bool));
|
|
|
|
}
|
2013-10-23 17:16:49 +04:00
|
|
|
|
|
|
|
already_AddRefed<nsIEventTarget>
|
|
|
|
CreateNewSyncLoop();
|
|
|
|
|
|
|
|
bool
|
|
|
|
RunCurrentSyncLoop();
|
|
|
|
|
2014-01-11 04:37:47 +04:00
|
|
|
bool
|
|
|
|
DestroySyncLoop(uint32_t aLoopIndex, nsIThreadInternal* aThread = nullptr);
|
|
|
|
|
2013-10-23 17:16:49 +04:00
|
|
|
void
|
|
|
|
InitializeGCTimers();
|
|
|
|
|
|
|
|
void
|
|
|
|
SetGCTimerMode(GCTimerMode aMode);
|
|
|
|
|
|
|
|
void
|
|
|
|
ShutdownGCTimers();
|
2011-07-17 23:09:13 +04:00
|
|
|
};
|
|
|
|
|
2013-11-05 18:16:24 +04:00
|
|
|
// This class is only used to trick the DOM bindings. We never create
|
|
|
|
// instances of it, and static_casting to it is fine since it doesn't add
|
|
|
|
// anything to WorkerPrivate.
|
|
|
|
class ChromeWorkerPrivate : public WorkerPrivate
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
static already_AddRefed<ChromeWorkerPrivate>
|
|
|
|
Constructor(const GlobalObject& aGlobal, const nsAString& aScriptURL,
|
|
|
|
ErrorResult& rv);
|
|
|
|
|
|
|
|
static bool
|
2014-08-05 06:20:35 +04:00
|
|
|
WorkerAvailable(JSContext* aCx, JSObject* /* unused */);
|
2013-11-05 18:16:24 +04:00
|
|
|
|
|
|
|
private:
|
2015-01-07 02:35:02 +03:00
|
|
|
ChromeWorkerPrivate() = delete;
|
|
|
|
ChromeWorkerPrivate(const ChromeWorkerPrivate& aRHS) = delete;
|
|
|
|
ChromeWorkerPrivate& operator =(const ChromeWorkerPrivate& aRHS) = delete;
|
2013-11-05 18:16:24 +04:00
|
|
|
};
|
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
WorkerPrivate*
|
|
|
|
GetWorkerPrivateFromContext(JSContext* aCx);
|
|
|
|
|
2013-11-05 18:16:24 +04:00
|
|
|
WorkerPrivate*
|
|
|
|
GetCurrentThreadWorkerPrivate();
|
|
|
|
|
2013-08-30 13:47:19 +04:00
|
|
|
bool
|
|
|
|
IsCurrentThreadRunningChromeWorker();
|
|
|
|
|
2013-09-09 07:29:21 +04:00
|
|
|
JSContext*
|
|
|
|
GetCurrentThreadJSContext();
|
|
|
|
|
2012-12-22 00:14:47 +04:00
|
|
|
class AutoSyncLoopHolder
|
|
|
|
{
|
2013-10-23 17:16:49 +04:00
|
|
|
WorkerPrivate* mWorkerPrivate;
|
|
|
|
nsCOMPtr<nsIEventTarget> mTarget;
|
2014-01-11 04:37:47 +04:00
|
|
|
uint32_t mIndex;
|
2013-10-23 17:16:49 +04:00
|
|
|
|
2012-12-22 00:14:47 +04:00
|
|
|
public:
|
2014-09-02 04:49:25 +04:00
|
|
|
explicit AutoSyncLoopHolder(WorkerPrivate* aWorkerPrivate)
|
2014-01-11 04:37:47 +04:00
|
|
|
: mWorkerPrivate(aWorkerPrivate)
|
|
|
|
, mTarget(aWorkerPrivate->CreateNewSyncLoop())
|
|
|
|
, mIndex(aWorkerPrivate->mSyncLoopStack.Length() - 1)
|
2012-12-22 00:14:47 +04:00
|
|
|
{
|
2013-10-23 17:16:49 +04:00
|
|
|
aWorkerPrivate->AssertIsOnWorkerThread();
|
2012-12-22 00:14:47 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
~AutoSyncLoopHolder()
|
|
|
|
{
|
|
|
|
if (mWorkerPrivate) {
|
2013-10-23 17:16:49 +04:00
|
|
|
mWorkerPrivate->AssertIsOnWorkerThread();
|
|
|
|
mWorkerPrivate->StopSyncLoop(mTarget, false);
|
2014-01-11 04:37:47 +04:00
|
|
|
mWorkerPrivate->DestroySyncLoop(mIndex);
|
2012-12-22 00:14:47 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2013-10-23 17:16:49 +04:00
|
|
|
Run()
|
2012-12-22 00:14:47 +04:00
|
|
|
{
|
|
|
|
WorkerPrivate* workerPrivate = mWorkerPrivate;
|
|
|
|
mWorkerPrivate = nullptr;
|
2013-10-23 17:16:49 +04:00
|
|
|
|
|
|
|
workerPrivate->AssertIsOnWorkerThread();
|
|
|
|
|
|
|
|
return workerPrivate->RunCurrentSyncLoop();
|
2012-12-22 00:14:47 +04:00
|
|
|
}
|
|
|
|
|
2013-10-23 17:16:49 +04:00
|
|
|
nsIEventTarget*
|
|
|
|
EventTarget() const
|
2012-12-22 00:14:47 +04:00
|
|
|
{
|
2013-10-23 17:16:49 +04:00
|
|
|
return mTarget;
|
2012-12-22 00:14:47 +04:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-07-23 18:30:27 +03:00
|
|
|
class TimerThreadEventTarget final : public nsIEventTarget
|
|
|
|
{
|
|
|
|
~TimerThreadEventTarget();
|
|
|
|
|
|
|
|
WorkerPrivate* mWorkerPrivate;
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<WorkerRunnable> mWorkerRunnable;
|
2015-07-23 18:30:27 +03:00
|
|
|
public:
|
|
|
|
NS_DECL_THREADSAFE_ISUPPORTS
|
|
|
|
|
|
|
|
TimerThreadEventTarget(WorkerPrivate* aWorkerPrivate,
|
|
|
|
WorkerRunnable* aWorkerRunnable);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
NS_IMETHOD
|
|
|
|
DispatchFromScript(nsIRunnable* aRunnable, uint32_t aFlags) override;
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHOD
|
|
|
|
Dispatch(already_AddRefed<nsIRunnable>&& aRunnable, uint32_t aFlags) override;
|
|
|
|
|
|
|
|
NS_IMETHOD
|
|
|
|
IsOnCurrentThread(bool* aIsOnCurrentThread) override;
|
|
|
|
};
|
|
|
|
|
2011-07-17 23:09:13 +04:00
|
|
|
END_WORKERS_NAMESPACE
|
|
|
|
|
|
|
|
#endif /* mozilla_dom_workers_workerprivate_h__ */
|