mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-26 06:38:36 +00:00
Backout changesets 58d026601240, c5a9a439d72c and cfdf675266b2 because of mochitest-3 crash
--HG-- extra : rebase_source : e6774b1220eabb7b9e2dce59bd487f48920d76b2
This commit is contained in:
parent
97f2b8fd25
commit
319f91efee
@ -57,6 +57,46 @@ ThirdPartyUtil::Init()
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Get the base domain for aHostURI; e.g. for "www.bbc.co.uk", this would be
|
||||
// "bbc.co.uk". Only properly-formed URI's are tolerated, though a trailing
|
||||
// dot may be present. If aHostURI is an IP address, an alias such as
|
||||
// 'localhost', an eTLD such as 'co.uk', or the empty string, aBaseDomain will
|
||||
// be the exact host. The result of this function should only be used in exact
|
||||
// string comparisons, since substring comparisons will not be valid for the
|
||||
// special cases elided above.
|
||||
nsresult
|
||||
ThirdPartyUtil::GetBaseDomain(nsIURI* aHostURI,
|
||||
nsCString& aBaseDomain)
|
||||
{
|
||||
// Get the base domain. this will fail if the host contains a leading dot,
|
||||
// more than one trailing dot, or is otherwise malformed.
|
||||
nsresult rv = mTLDService->GetBaseDomain(aHostURI, 0, aBaseDomain);
|
||||
if (rv == NS_ERROR_HOST_IS_IP_ADDRESS ||
|
||||
rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
|
||||
// aHostURI is either an IP address, an alias such as 'localhost', an eTLD
|
||||
// such as 'co.uk', or the empty string. Uses the normalized host in such
|
||||
// cases.
|
||||
rv = aHostURI->GetAsciiHost(aBaseDomain);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// aHostURI (and thus aBaseDomain) may be the string '.'. If so, fail.
|
||||
if (aBaseDomain.Length() == 1 && aBaseDomain.Last() == '.')
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
// Reject any URIs without a host that aren't file:// URIs. This makes it the
|
||||
// only way we can get a base domain consisting of the empty string, which
|
||||
// means we can safely perform foreign tests on such URIs where "not foreign"
|
||||
// means "the involved URIs are all file://".
|
||||
if (aBaseDomain.IsEmpty()) {
|
||||
PRBool isFileURI = PR_FALSE;
|
||||
aHostURI->SchemeIs("file", &isFileURI);
|
||||
NS_ENSURE_TRUE(isFileURI, NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Determine if aFirstDomain is a different base domain to aSecondURI; or, if
|
||||
// the concept of base domain does not apply, determine if the two hosts are not
|
||||
// string-identical.
|
||||
@ -276,42 +316,3 @@ ThirdPartyUtil::IsThirdPartyChannel(nsIChannel* aChannel,
|
||||
return IsThirdPartyWindow(ourWin, channelURI, aResult);
|
||||
}
|
||||
|
||||
// Get the base domain for aHostURI; e.g. for "www.bbc.co.uk", this would be
|
||||
// "bbc.co.uk". Only properly-formed URI's are tolerated, though a trailing
|
||||
// dot may be present. If aHostURI is an IP address, an alias such as
|
||||
// 'localhost', an eTLD such as 'co.uk', or the empty string, aBaseDomain will
|
||||
// be the exact host. The result of this function should only be used in exact
|
||||
// string comparisons, since substring comparisons will not be valid for the
|
||||
// special cases elided above.
|
||||
NS_IMETHODIMP
|
||||
ThirdPartyUtil::GetBaseDomain(nsIURI* aHostURI,
|
||||
nsACString& aBaseDomain)
|
||||
{
|
||||
// Get the base domain. this will fail if the host contains a leading dot,
|
||||
// more than one trailing dot, or is otherwise malformed.
|
||||
nsresult rv = mTLDService->GetBaseDomain(aHostURI, 0, aBaseDomain);
|
||||
if (rv == NS_ERROR_HOST_IS_IP_ADDRESS ||
|
||||
rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
|
||||
// aHostURI is either an IP address, an alias such as 'localhost', an eTLD
|
||||
// such as 'co.uk', or the empty string. Uses the normalized host in such
|
||||
// cases.
|
||||
rv = aHostURI->GetAsciiHost(aBaseDomain);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// aHostURI (and thus aBaseDomain) may be the string '.'. If so, fail.
|
||||
if (aBaseDomain.Length() == 1 && aBaseDomain.Last() == '.')
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
// Reject any URIs without a host that aren't file:// URIs. This makes it the
|
||||
// only way we can get a base domain consisting of the empty string, which
|
||||
// means we can safely perform foreign tests on such URIs where "not foreign"
|
||||
// means "the involved URIs are all file://".
|
||||
if (aBaseDomain.IsEmpty()) {
|
||||
PRBool isFileURI = PR_FALSE;
|
||||
aHostURI->SchemeIs("file", &isFileURI);
|
||||
NS_ENSURE_TRUE(isFileURI, NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ public:
|
||||
nsresult Init();
|
||||
|
||||
private:
|
||||
nsresult GetBaseDomain(nsIURI* aHostURI, nsCString& aBaseDomain);
|
||||
nsresult IsThirdPartyInternal(const nsCString& aFirstDomain,
|
||||
nsIURI* aSecondURI, PRBool* aResult);
|
||||
static already_AddRefed<nsIURI> GetURIFromWindow(nsIDOMWindow* aWin);
|
||||
|
@ -45,10 +45,6 @@
|
||||
#include "nsNativeCharsetUtils.h"
|
||||
#include "nsStringGlue.h"
|
||||
|
||||
#include "WorkerPrivate.h"
|
||||
|
||||
#define CTYPES_STR "ctypes"
|
||||
|
||||
USING_WORKERS_NAMESPACE
|
||||
|
||||
namespace {
|
||||
@ -78,57 +74,8 @@ UnicodeToNative(JSContext* aCx, const jschar* aSource, size_t aSourceLen)
|
||||
JSCTypesCallbacks gCTypesCallbacks = {
|
||||
UnicodeToNative
|
||||
};
|
||||
|
||||
JSBool
|
||||
CTypesLazyGetter(JSContext* aCx, JSObject* aObj, jsid aId, jsval* aVp)
|
||||
{
|
||||
NS_ASSERTION(JS_GetGlobalObject(aCx) == aObj, "Not a global object!");
|
||||
NS_ASSERTION(JSID_IS_STRING(aId), "Bad id!");
|
||||
NS_ASSERTION(JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(aId), CTYPES_STR),
|
||||
"Bad id!");
|
||||
|
||||
WorkerPrivate* worker = GetWorkerPrivateFromContext(aCx);
|
||||
NS_ASSERTION(worker->IsChromeWorker(), "This should always be true!");
|
||||
|
||||
if (!worker->DisableMemoryReporter()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
jsval ctypes;
|
||||
return JS_DeletePropertyById(aCx, aObj, aId) &&
|
||||
JS_InitCTypesClass(aCx, aObj) &&
|
||||
JS_GetPropertyById(aCx, aObj, aId, &ctypes) &&
|
||||
JS_SetCTypesCallbacks(aCx, JSVAL_TO_OBJECT(ctypes),
|
||||
&gCTypesCallbacks) &&
|
||||
JS_GetPropertyById(aCx, aObj, aId, aVp);
|
||||
}
|
||||
#endif
|
||||
|
||||
inline bool
|
||||
DefineCTypesLazyGetter(JSContext* aCx, JSObject* aGlobal)
|
||||
{
|
||||
#ifdef BUILD_CTYPES
|
||||
{
|
||||
JSString* ctypesStr = JS_InternString(aCx, CTYPES_STR);
|
||||
if (!ctypesStr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
jsid ctypesId = INTERNED_STRING_TO_JSID(aCx, ctypesStr);
|
||||
|
||||
// We use a lazy getter here to let us unregister the blocking memory
|
||||
// reporter since ctypes can easily block the worker thread and we can
|
||||
// deadlock. Remove once bug 673323 is fixed.
|
||||
if (!JS_DefinePropertyById(aCx, aGlobal, ctypesId, JSVAL_VOID,
|
||||
CTypesLazyGetter, NULL, 0)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
BEGIN_WORKERS_NAMESPACE
|
||||
@ -138,8 +85,16 @@ namespace chromeworker {
|
||||
bool
|
||||
DefineChromeWorkerFunctions(JSContext* aCx, JSObject* aGlobal)
|
||||
{
|
||||
// Currently ctypes is the only special property given to ChromeWorkers.
|
||||
return DefineCTypesLazyGetter(aCx, aGlobal);
|
||||
#ifdef BUILD_CTYPES
|
||||
jsval ctypes;
|
||||
if (!JS_InitCTypesClass(aCx, aGlobal) ||
|
||||
!JS_GetProperty(aCx, aGlobal, "ctypes", &ctypes) ||
|
||||
!JS_SetCTypesCallbacks(aCx, JSVAL_TO_OBJECT(ctypes), &gCTypesCallbacks)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace chromeworker
|
||||
|
@ -141,9 +141,7 @@ EventTarget::AddEventListener(JSContext* aCx, uintN aArgc, jsval* aVp)
|
||||
JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
|
||||
|
||||
EventTarget* self = GetPrivate(aCx, obj);
|
||||
if (!self) {
|
||||
return true;
|
||||
}
|
||||
JS_ASSERT(self);
|
||||
|
||||
JSString* type;
|
||||
JSObject* listener;
|
||||
@ -169,9 +167,7 @@ EventTarget::RemoveEventListener(JSContext* aCx, uintN aArgc, jsval* aVp)
|
||||
JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
|
||||
|
||||
EventTarget* self = GetPrivate(aCx, obj);
|
||||
if (!self) {
|
||||
return true;
|
||||
}
|
||||
JS_ASSERT(self);
|
||||
|
||||
JSString* type;
|
||||
JSObject* listener;
|
||||
@ -197,9 +193,7 @@ EventTarget::DispatchEvent(JSContext* aCx, uintN aArgc, jsval* aVp)
|
||||
JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
|
||||
|
||||
EventTarget* self = GetPrivate(aCx, obj);
|
||||
if (!self) {
|
||||
return true;
|
||||
}
|
||||
JS_ASSERT(self);
|
||||
|
||||
JSObject* event;
|
||||
if (!JS_ConvertArguments(aCx, aArgc, JS_ARGV(aCx, aVp), "o", &event)) {
|
||||
|
@ -46,11 +46,13 @@
|
||||
#include "nsIPlatformCharset.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIJSContextStack.h"
|
||||
#include "nsIMemoryReporter.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsISupportsPriority.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
#include "jsprf.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsDOMJSUtils.h"
|
||||
@ -285,6 +287,61 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate)
|
||||
return workerCx;
|
||||
}
|
||||
|
||||
class WorkerMemoryReporter : public nsIMemoryMultiReporter
|
||||
{
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
nsCString mPathPrefix;
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
WorkerMemoryReporter(WorkerPrivate* aWorkerPrivate)
|
||||
: mWorkerPrivate(aWorkerPrivate)
|
||||
{
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
nsCString escapedDomain(aWorkerPrivate->Domain());
|
||||
escapedDomain.ReplaceChar('/', '\\');
|
||||
|
||||
NS_ConvertUTF16toUTF8 escapedURL(aWorkerPrivate->ScriptURL());
|
||||
escapedURL.ReplaceChar('/', '\\');
|
||||
|
||||
// 64bit address plus '0x' plus null terminator.
|
||||
char address[21];
|
||||
JSUint32 addressSize =
|
||||
JS_snprintf(address, sizeof(address), "0x%llx", aWorkerPrivate);
|
||||
if (addressSize == JSUint32(-1)) {
|
||||
NS_WARNING("JS_snprintf failed!");
|
||||
address[0] = '\0';
|
||||
addressSize = 0;
|
||||
}
|
||||
|
||||
mPathPrefix = NS_LITERAL_CSTRING("explicit/dom/workers(") +
|
||||
escapedDomain + NS_LITERAL_CSTRING(")/worker(") +
|
||||
escapedURL + NS_LITERAL_CSTRING(", ") +
|
||||
nsDependentCString(address, addressSize) +
|
||||
NS_LITERAL_CSTRING(")/");
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
CollectReports(nsIMemoryMultiReporterCallback* aCallback,
|
||||
nsISupports* aClosure)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
IterateData data;
|
||||
if (!mWorkerPrivate->BlockAndCollectRuntimeStats(&data)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
ReportJSRuntimeStats(data, mPathPrefix, aCallback, aClosure);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(WorkerMemoryReporter, nsIMemoryMultiReporter)
|
||||
|
||||
class WorkerThreadRunnable : public nsRunnable
|
||||
{
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
@ -311,11 +368,25 @@ public:
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsRefPtr<WorkerMemoryReporter> reporter =
|
||||
new WorkerMemoryReporter(workerPrivate);
|
||||
if (NS_FAILED(NS_RegisterMemoryMultiReporter(reporter))) {
|
||||
NS_WARNING("Failed to register memory reporter!");
|
||||
reporter = nsnull;
|
||||
}
|
||||
|
||||
{
|
||||
JSAutoRequest ar(cx);
|
||||
workerPrivate->DoRunLoop(cx);
|
||||
}
|
||||
|
||||
if (reporter) {
|
||||
if (NS_FAILED(NS_UnregisterMemoryMultiReporter(reporter))) {
|
||||
NS_WARNING("Failed to unregister memory reporter!");
|
||||
}
|
||||
reporter = nsnull;
|
||||
}
|
||||
|
||||
JSRuntime* rt = JS_GetRuntime(cx);
|
||||
|
||||
// XXX Bug 666963 - CTypes can create another JSContext for use with
|
||||
|
@ -112,27 +112,6 @@ public:
|
||||
return proto;
|
||||
}
|
||||
|
||||
static void
|
||||
ClearPrivateSlot(JSContext* aCx, JSObject* aObj)
|
||||
{
|
||||
JS_ASSERT(!JS_IsExceptionPending(aCx));
|
||||
|
||||
WorkerPrivate* worker = GetJSPrivateSafeish<WorkerPrivate>(aCx, aObj);
|
||||
JS_ASSERT(worker);
|
||||
|
||||
for (int index = 0; index < STRING_COUNT; index++) {
|
||||
const char* name = sEventStrings[index];
|
||||
jsval listener;
|
||||
if (!worker->GetEventListenerOnEventTarget(aCx, name + 2, &listener) ||
|
||||
!JS_DefineProperty(aCx, aObj, name, listener, NULL, NULL,
|
||||
(PROPERTY_FLAGS & ~JSPROP_SHARED))) {
|
||||
JS_ClearPendingException(aCx);
|
||||
}
|
||||
}
|
||||
|
||||
SetJSPrivateSafeish(aCx, aObj, NULL);
|
||||
}
|
||||
|
||||
protected:
|
||||
static WorkerPrivate*
|
||||
GetInstancePrivate(JSContext* aCx, JSObject* aObj, const char* aFunctionName);
|
||||
@ -358,12 +337,6 @@ public:
|
||||
return proto;
|
||||
}
|
||||
|
||||
static void
|
||||
ClearPrivateSlot(JSContext* aCx, JSObject* aObj)
|
||||
{
|
||||
Worker::ClearPrivateSlot(aCx, aObj);
|
||||
}
|
||||
|
||||
private:
|
||||
// No instance of this class should ever be created so these are explicitly
|
||||
// left without an implementation to prevent linking in case someone tries to
|
||||
@ -452,20 +425,6 @@ InitClass(JSContext* aCx, JSObject* aGlobal, JSObject* aProto,
|
||||
return Worker::InitClass(aCx, aGlobal, aProto, aMainRuntime);
|
||||
}
|
||||
|
||||
void
|
||||
ClearPrivateSlot(JSContext* aCx, JSObject* aObj)
|
||||
{
|
||||
JSClass* clasp = JS_GET_CLASS(aCx, aObj);
|
||||
JS_ASSERT(clasp == Worker::Class() || clasp == ChromeWorker::Class());
|
||||
|
||||
if (clasp == ChromeWorker::Class()) {
|
||||
ChromeWorker::ClearPrivateSlot(aCx, aObj);
|
||||
}
|
||||
else {
|
||||
Worker::ClearPrivateSlot(aCx, aObj);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace worker
|
||||
|
||||
namespace chromeworker {
|
||||
|
@ -51,9 +51,6 @@ JSObject*
|
||||
InitClass(JSContext* aCx, JSObject* aGlobal, JSObject* aProto,
|
||||
bool aMainRuntime);
|
||||
|
||||
void
|
||||
ClearPrivateSlot(JSContext* aCx, JSObject* aObj);
|
||||
|
||||
} // namespace worker
|
||||
|
||||
namespace chromeworker {
|
||||
|
@ -39,13 +39,12 @@
|
||||
|
||||
#include "WorkerPrivate.h"
|
||||
|
||||
#include "mozIThirdPartyUtil.h"
|
||||
#include "nsIClassInfo.h"
|
||||
#include "nsIConsoleService.h"
|
||||
#include "nsIDOMFile.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIEffectiveTLDService.h"
|
||||
#include "nsIJSContextStack.h"
|
||||
#include "nsIMemoryReporter.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
@ -58,7 +57,6 @@
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "jsprf.h"
|
||||
#include "nsAlgorithm.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsDOMClassInfo.h"
|
||||
@ -76,7 +74,6 @@
|
||||
#include "Principal.h"
|
||||
#include "RuntimeService.h"
|
||||
#include "ScriptLoader.h"
|
||||
#include "Worker.h"
|
||||
#include "WorkerFeature.h"
|
||||
#include "WorkerScope.h"
|
||||
|
||||
@ -143,87 +140,6 @@ SwapToISupportsArray(SmartPtr<T>& aSrc,
|
||||
dest->swap(rawSupports);
|
||||
}
|
||||
|
||||
class WorkerMemoryReporter : public nsIMemoryMultiReporter
|
||||
{
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
nsCString mAddressString;
|
||||
nsCString mPathPrefix;
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
WorkerMemoryReporter(WorkerPrivate* aWorkerPrivate)
|
||||
: mWorkerPrivate(aWorkerPrivate)
|
||||
{
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
nsCString escapedDomain(aWorkerPrivate->Domain());
|
||||
escapedDomain.ReplaceChar('/', '\\');
|
||||
|
||||
NS_ConvertUTF16toUTF8 escapedURL(aWorkerPrivate->ScriptURL());
|
||||
escapedURL.ReplaceChar('/', '\\');
|
||||
|
||||
{
|
||||
// 64bit address plus '0x' plus null terminator.
|
||||
char address[21];
|
||||
JSUint32 addressSize =
|
||||
JS_snprintf(address, sizeof(address), "0x%llx", aWorkerPrivate);
|
||||
if (addressSize != JSUint32(-1)) {
|
||||
mAddressString.Assign(address, addressSize);
|
||||
}
|
||||
else {
|
||||
NS_WARNING("JS_snprintf failed!");
|
||||
mAddressString.AssignLiteral("<unknown address>");
|
||||
}
|
||||
}
|
||||
|
||||
mPathPrefix = NS_LITERAL_CSTRING("explicit/dom/workers(") +
|
||||
escapedDomain + NS_LITERAL_CSTRING(")/worker(") +
|
||||
escapedURL + NS_LITERAL_CSTRING(", ") + mAddressString +
|
||||
NS_LITERAL_CSTRING(")/");
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
CollectReports(nsIMemoryMultiReporterCallback* aCallback,
|
||||
nsISupports* aClosure)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
IterateData data;
|
||||
|
||||
if (mWorkerPrivate) {
|
||||
bool disabled;
|
||||
if (!mWorkerPrivate->BlockAndCollectRuntimeStats(&data, &disabled)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Don't ever try to talk to the worker again.
|
||||
if (disabled) {
|
||||
#ifdef DEBUG
|
||||
{
|
||||
nsCAutoString message("Unable to report memory for ");
|
||||
if (mWorkerPrivate->IsChromeWorker()) {
|
||||
message.AppendLiteral("Chrome");
|
||||
}
|
||||
message += NS_LITERAL_CSTRING("Worker (") + mAddressString +
|
||||
NS_LITERAL_CSTRING(")! It is either using ctypes or is in "
|
||||
"the process of being destroyed");
|
||||
NS_WARNING(message.get());
|
||||
}
|
||||
#endif
|
||||
mWorkerPrivate = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
// Always report, even if we're disabled, so that we at least get an entry
|
||||
// in about::memory.
|
||||
ReportJSRuntimeStats(data, mPathPrefix, aCallback, aClosure);
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(WorkerMemoryReporter, nsIMemoryMultiReporter)
|
||||
|
||||
struct WorkerStructuredCloneCallbacks
|
||||
{
|
||||
static JSObject*
|
||||
@ -1366,19 +1282,19 @@ class CollectRuntimeStatsRunnable : public WorkerControlRunnable
|
||||
typedef mozilla::Mutex Mutex;
|
||||
typedef mozilla::CondVar CondVar;
|
||||
|
||||
Mutex mMutex;
|
||||
CondVar mCondVar;
|
||||
volatile bool mDone;
|
||||
Mutex* mMutex;
|
||||
CondVar* mCondVar;
|
||||
volatile bool* mDoneFlag;
|
||||
IterateData* mData;
|
||||
bool* mSucceeded;
|
||||
volatile bool* mSucceeded;
|
||||
|
||||
public:
|
||||
CollectRuntimeStatsRunnable(WorkerPrivate* aWorkerPrivate, IterateData* aData,
|
||||
bool* aSucceeded)
|
||||
CollectRuntimeStatsRunnable(WorkerPrivate* aWorkerPrivate, Mutex* aMutex,
|
||||
CondVar* aCondVar, volatile bool* aDoneFlag,
|
||||
IterateData* aData, volatile bool* aSucceeded)
|
||||
: WorkerControlRunnable(aWorkerPrivate, WorkerThread, UnchangedBusyCount),
|
||||
mMutex("CollectRuntimeStatsRunnable::mMutex"),
|
||||
mCondVar(mMutex, "CollectRuntimeStatsRunnable::mCondVar"), mDone(false),
|
||||
mData(aData), mSucceeded(aSucceeded)
|
||||
mMutex(aMutex), mCondVar(aCondVar), mDoneFlag(aDoneFlag), mData(aData),
|
||||
mSucceeded(aSucceeded)
|
||||
{ }
|
||||
|
||||
bool
|
||||
@ -1395,26 +1311,6 @@ public:
|
||||
AssertIsOnMainThread();
|
||||
}
|
||||
|
||||
bool
|
||||
DispatchInternal()
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (!WorkerControlRunnable::DispatchInternal()) {
|
||||
NS_WARNING("Failed to dispatch runnable!");
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
while (!mDone) {
|
||||
mCondVar.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
||||
{
|
||||
@ -1423,9 +1319,12 @@ public:
|
||||
*mSucceeded = CollectCompartmentStatsForRuntime(JS_GetRuntime(aCx), mData);
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
mDone = true;
|
||||
mCondVar.Notify();
|
||||
MutexAutoLock lock(*mMutex);
|
||||
|
||||
NS_ASSERTION(!*mDoneFlag, "Should be false!");
|
||||
|
||||
*mDoneFlag = true;
|
||||
mCondVar->Notify();
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1874,7 +1773,7 @@ WorkerPrivateParent<Derived>::FinalizeInstance(JSContext* aCx)
|
||||
|
||||
if (mJSObject) {
|
||||
// Decouple the object from the private now.
|
||||
worker::ClearPrivateSlot(aCx, mJSObject);
|
||||
SetJSPrivateSafeish(aCx, mJSObject, nsnull);
|
||||
|
||||
// Clear the JS object.
|
||||
mJSObject = nsnull;
|
||||
@ -2202,8 +2101,7 @@ WorkerPrivate::WorkerPrivate(JSContext* aCx, JSObject* aObject,
|
||||
mJSContext(nsnull), mErrorHandlerRecursionCount(0), mNextTimeoutId(1),
|
||||
mStatus(Pending), mSuspended(false), mTimerRunning(false),
|
||||
mRunningExpiredTimeouts(false), mCloseHandlerStarted(false),
|
||||
mCloseHandlerFinished(false), mMemoryReporterRunning(false),
|
||||
mMemoryReporterDisabled(false)
|
||||
mCloseHandlerFinished(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(mozilla::dom::workers::WorkerPrivate);
|
||||
}
|
||||
@ -2330,14 +2228,14 @@ WorkerPrivate::Create(JSContext* aCx, JSObject* aObj, WorkerPrivate* aParent,
|
||||
domain = file;
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
|
||||
do_GetService(THIRDPARTYUTIL_CONTRACTID);
|
||||
if (!thirdPartyUtil) {
|
||||
JS_ReportError(aCx, "Could not get third party helper service!");
|
||||
nsCOMPtr<nsIEffectiveTLDService> tldService =
|
||||
do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
|
||||
if (!tldService) {
|
||||
JS_ReportError(aCx, "Could not get TLD service!");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (NS_FAILED(thirdPartyUtil->GetBaseDomain(codebase, domain))) {
|
||||
if (NS_FAILED(tldService->GetBaseDomain(codebase, 0, domain))) {
|
||||
JS_ReportError(aCx, "Could not get domain!");
|
||||
return nsnull;
|
||||
}
|
||||
@ -2410,13 +2308,6 @@ WorkerPrivate::DoRunLoop(JSContext* aCx)
|
||||
mStatus = Running;
|
||||
}
|
||||
|
||||
mMemoryReporter = new WorkerMemoryReporter(this);
|
||||
|
||||
if (NS_FAILED(NS_RegisterMemoryMultiReporter(mMemoryReporter))) {
|
||||
NS_WARNING("Failed to register memory reporter!");
|
||||
mMemoryReporter = nsnull;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
Status currentStatus;
|
||||
nsIRunnable* event;
|
||||
@ -2467,17 +2358,6 @@ WorkerPrivate::DoRunLoop(JSContext* aCx)
|
||||
|
||||
// If we're supposed to die then we should exit the loop.
|
||||
if (currentStatus == Killing) {
|
||||
// Call this before unregistering the reporter as we may be racing with
|
||||
// the main thread.
|
||||
DisableMemoryReporter();
|
||||
|
||||
if (mMemoryReporter) {
|
||||
if (NS_FAILED(NS_UnregisterMemoryMultiReporter(mMemoryReporter))) {
|
||||
NS_WARNING("Failed to unregister memory reporter!");
|
||||
}
|
||||
mMemoryReporter = nsnull;
|
||||
}
|
||||
|
||||
StopAcceptingEvents();
|
||||
return;
|
||||
}
|
||||
@ -2496,7 +2376,21 @@ WorkerPrivate::OperationCallback(JSContext* aCx)
|
||||
|
||||
for (;;) {
|
||||
// Run all control events now.
|
||||
mayContinue = ProcessAllControlRunnables();
|
||||
for (;;) {
|
||||
nsIRunnable* event;
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
if (!mControlQueue.Pop(event)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_FAILED(event->Run())) {
|
||||
mayContinue = false;
|
||||
}
|
||||
|
||||
NS_RELEASE(event);
|
||||
}
|
||||
|
||||
if (!mayContinue || !mSuspended) {
|
||||
break;
|
||||
@ -2563,86 +2457,35 @@ WorkerPrivate::ScheduleDeletion(bool aWasPending)
|
||||
}
|
||||
|
||||
bool
|
||||
WorkerPrivate::BlockAndCollectRuntimeStats(IterateData* aData, bool* aDisabled)
|
||||
WorkerPrivate::BlockAndCollectRuntimeStats(IterateData* aData)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
mMutex.AssertNotCurrentThreadOwns();
|
||||
NS_ASSERTION(aData, "Null data!");
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
if (mMemoryReporterDisabled) {
|
||||
*aDisabled = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
*aDisabled = false;
|
||||
mMemoryReporterRunning = true;
|
||||
}
|
||||
|
||||
bool succeeded;
|
||||
mozilla::Mutex mutex("BlockAndCollectRuntimeStats mutex");
|
||||
mozilla::CondVar condvar(mutex, "BlockAndCollectRuntimeStats condvar");
|
||||
volatile bool doneFlag = false;
|
||||
volatile bool succeeded = false;
|
||||
|
||||
nsRefPtr<CollectRuntimeStatsRunnable> runnable =
|
||||
new CollectRuntimeStatsRunnable(this, aData, &succeeded);
|
||||
new CollectRuntimeStatsRunnable(this, &mutex, &condvar, &doneFlag, aData,
|
||||
&succeeded);
|
||||
if (!runnable->Dispatch(nsnull)) {
|
||||
NS_WARNING("Failed to dispatch runnable!");
|
||||
succeeded = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
mMemoryReporterRunning = false;
|
||||
MutexAutoLock lock(mutex);
|
||||
while (!doneFlag) {
|
||||
condvar.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
bool
|
||||
WorkerPrivate::DisableMemoryReporter()
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
|
||||
bool result = true;
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
mMemoryReporterDisabled = true;
|
||||
|
||||
while (mMemoryReporterRunning) {
|
||||
MutexAutoUnlock unlock(mMutex);
|
||||
result = ProcessAllControlRunnables() && result;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
WorkerPrivate::ProcessAllControlRunnables()
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
|
||||
bool result = true;
|
||||
|
||||
for (;;) {
|
||||
nsIRunnable* event;
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
if (!mControlQueue.Pop(event)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_FAILED(event->Run())) {
|
||||
result = false;
|
||||
}
|
||||
|
||||
NS_RELEASE(event);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
WorkerPrivate::Dispatch(WorkerRunnable* aEvent, EventQueue* aQueue)
|
||||
{
|
||||
|
@ -63,7 +63,6 @@
|
||||
class JSAutoStructuredCloneBuffer;
|
||||
class nsIDocument;
|
||||
class nsIPrincipal;
|
||||
class nsIMemoryMultiReporter;
|
||||
class nsIScriptContext;
|
||||
class nsIURI;
|
||||
class nsPIDOMWindow;
|
||||
@ -513,7 +512,6 @@ class WorkerPrivate : public WorkerPrivateParent<WorkerPrivate>
|
||||
nsTArray<nsAutoPtr<TimeoutInfo> > mTimeouts;
|
||||
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
nsCOMPtr<nsIMemoryMultiReporter> mMemoryReporter;
|
||||
|
||||
mozilla::TimeStamp mKillTime;
|
||||
PRUint32 mErrorHandlerRecursionCount;
|
||||
@ -524,8 +522,6 @@ class WorkerPrivate : public WorkerPrivateParent<WorkerPrivate>
|
||||
bool mRunningExpiredTimeouts;
|
||||
bool mCloseHandlerStarted;
|
||||
bool mCloseHandlerFinished;
|
||||
bool mMemoryReporterRunning;
|
||||
bool mMemoryReporterDisabled;
|
||||
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsIThread> mThread;
|
||||
@ -658,11 +654,7 @@ public:
|
||||
ScheduleDeletion(bool aWasPending);
|
||||
|
||||
bool
|
||||
BlockAndCollectRuntimeStats(mozilla::xpconnect::memory::IterateData* aData,
|
||||
bool* aDisabled);
|
||||
|
||||
bool
|
||||
DisableMemoryReporter();
|
||||
BlockAndCollectRuntimeStats(mozilla::xpconnect::memory::IterateData* aData);
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
void
|
||||
@ -751,9 +743,6 @@ private:
|
||||
ClearQueue(&mQueue);
|
||||
ClearQueue(&mControlQueue);
|
||||
}
|
||||
|
||||
bool
|
||||
ProcessAllControlRunnables();
|
||||
};
|
||||
|
||||
WorkerPrivate*
|
||||
|
@ -58,9 +58,6 @@ _TEST_FILES = \
|
||||
errorPropagation_worker.js \
|
||||
test_eventDispatch.html \
|
||||
eventDispatch_worker.js \
|
||||
test_ipAddressOrigin.html \
|
||||
ipAddressOrigin_iframe.html \
|
||||
ipAddressOrigin_worker.js \
|
||||
test_importScripts.html \
|
||||
importScripts_worker.js \
|
||||
importScripts_worker_imported1.js \
|
||||
|
@ -6,11 +6,6 @@ if (!("ctypes" in self)) {
|
||||
throw "No ctypes!";
|
||||
}
|
||||
|
||||
// Go ahead and verify that the ctypes lazy getter actually works.
|
||||
if (ctypes.toString() != "[object ctypes]") {
|
||||
throw "Bad ctypes object: " + ctypes.toString();
|
||||
}
|
||||
|
||||
onmessage = function(event) {
|
||||
let worker = new ChromeWorker("chromeWorker_subworker.js");
|
||||
worker.onmessage = function(event) {
|
||||
|
@ -1,23 +0,0 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
onmessage = function (event) {
|
||||
var url = "http://127.0.0.1" +
|
||||
window.location.pathname.replace("ipAddressOrigin_iframe.html",
|
||||
"ipAddRessOrigin_worker.js");
|
||||
|
||||
var worker = new Worker(url);
|
||||
worker.onmessage = function (event) {
|
||||
window.parent.postMessage(event.data, "*");
|
||||
};
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,5 +0,0 @@
|
||||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
postMessage("done");
|
@ -1,42 +0,0 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Web Workers</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body onload="go();">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
<iframe id="testFrame"></iframe>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
function go() {
|
||||
var iframe = document.getElementById("testFrame");
|
||||
|
||||
iframe.addEventListener("load", function() {
|
||||
iframe.contentWindow.postMessage("go", "*");
|
||||
window.addEventListener("message", function(event) {
|
||||
is(event.data, "done", "Correct message");
|
||||
SimpleTest.finish();
|
||||
}, "false");
|
||||
}, false);
|
||||
|
||||
iframe.src =
|
||||
"http://127.0.0.1" +
|
||||
window.location.pathname.replace("test_ipAddressOrigin.html",
|
||||
"ipAddressOrigin_iframe.html");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -26,43 +26,6 @@ Tests of DOM Worker terminate feature
|
||||
|
||||
var interval;
|
||||
|
||||
var worker;
|
||||
|
||||
function messageListener(event) {
|
||||
is(event.data, "Still alive!", "Correct message!");
|
||||
if (messageCount++ == 20) {
|
||||
ok(worker.onmessage === messageListener,
|
||||
"Correct listener before terminate");
|
||||
|
||||
worker.terminate();
|
||||
|
||||
var exception = false;
|
||||
try {
|
||||
worker.addEventListener("message", messageListener, false);
|
||||
}
|
||||
catch (e) {
|
||||
exception = true;
|
||||
}
|
||||
is(exception, false, "addEventListener didn't throw after terminate");
|
||||
|
||||
exception = false;
|
||||
try {
|
||||
worker.removeEventListener("message", messageListener, false);
|
||||
}
|
||||
catch (e) {
|
||||
exception = true;
|
||||
}
|
||||
is(exception, false, "removeEventListener didn't throw after terminate");
|
||||
|
||||
ok(worker.onmessage === messageListener,
|
||||
"Correct listener after terminate");
|
||||
|
||||
worker.onmessage = function(event) { }
|
||||
|
||||
interval = setInterval(testCount, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
function testCount() {
|
||||
is(messageCount, 21, "Received another message after terminated!");
|
||||
if (intervalCount++ == 5) {
|
||||
@ -71,8 +34,19 @@ Tests of DOM Worker terminate feature
|
||||
}
|
||||
}
|
||||
|
||||
worker = new Worker("terminate_worker.js");
|
||||
worker.onmessage = messageListener;
|
||||
var worker = new Worker("terminate_worker.js");
|
||||
worker.onmessage = function(event) {
|
||||
is(event.data, "Still alive!", "Bad message!");
|
||||
if (messageCount++ == 20) {
|
||||
worker.terminate();
|
||||
interval = setInterval(testCount, 1000);
|
||||
}
|
||||
};
|
||||
|
||||
worker.onerror = function(event) {
|
||||
ok(false, "Worker had an error: " + event.data);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
|
@ -45,7 +45,7 @@ interface nsIChannel;
|
||||
* Utility functions for determining whether a given URI, channel, or window
|
||||
* hierarchy is third party with respect to a known URI.
|
||||
*/
|
||||
[scriptable, uuid(d994fd1d-d2fe-4372-9ae7-88b08b7d9d90)]
|
||||
[scriptable, uuid(55385caa-1b94-4376-a34c-b47c51ef0837)]
|
||||
interface mozIThirdPartyUtil : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -155,24 +155,6 @@ interface mozIThirdPartyUtil : nsISupports
|
||||
* @see isThirdPartyWindow
|
||||
*/
|
||||
boolean isThirdPartyChannel(in nsIChannel aChannel, [optional] in nsIURI aURI);
|
||||
|
||||
/**
|
||||
* getBaseDomain
|
||||
*
|
||||
* Get the base domain for aHostURI; e.g. for "www.bbc.co.uk", this would be
|
||||
* "bbc.co.uk". Only properly-formed URI's are tolerated, though a trailing
|
||||
* dot may be present. If aHostURI is an IP address, an alias such as
|
||||
* 'localhost', an eTLD such as 'co.uk', or the empty string, aBaseDomain will
|
||||
* be the exact host. The result of this function should only be used in exact
|
||||
* string comparisons, since substring comparisons will not be valid for the
|
||||
* special cases elided above.
|
||||
*
|
||||
* @param aHostURI
|
||||
* The URI to analyze.
|
||||
*
|
||||
* @return the base domain.
|
||||
*/
|
||||
AUTF8String getBaseDomain(in nsIURI aHostURI);
|
||||
};
|
||||
|
||||
%{ C++
|
||||
|
Loading…
x
Reference in New Issue
Block a user