mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 00:35:44 +00:00
Merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
commit
7c20ad9250
@ -36,6 +36,7 @@
|
||||
#include "mozilla/ipc/PBackgroundChild.h"
|
||||
#include "mozilla/ipc/PBackgroundParent.h"
|
||||
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsInterfaceHashtable.h"
|
||||
@ -2171,9 +2172,9 @@ class LSRequestBase : public DatastoreOperationBase,
|
||||
// IPDL methods.
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
private:
|
||||
mozilla::ipc::IPCResult RecvCancel() final;
|
||||
mozilla::ipc::IPCResult RecvCancel() override;
|
||||
|
||||
private:
|
||||
mozilla::ipc::IPCResult RecvFinish() final;
|
||||
};
|
||||
|
||||
@ -2343,6 +2344,8 @@ class PrepareDatastoreOp : public LSRequestBase, public OpenDirectoryListener {
|
||||
// IPDL overrides.
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvCancel() final;
|
||||
|
||||
// OpenDirectoryListener overrides.
|
||||
void DirectoryLockAcquired(DirectoryLock* aLock) override;
|
||||
|
||||
@ -2739,6 +2742,8 @@ StaticAutoPtr<ArchivedOriginHashtable> gArchivedOrigins;
|
||||
// Can only be touched on the Quota Manager I/O thread.
|
||||
bool gInitializedShadowStorage = false;
|
||||
|
||||
LazyLogModule gLogger("LocalStorage");
|
||||
|
||||
bool IsOnConnectionThread() {
|
||||
MOZ_ASSERT(gConnectionThread);
|
||||
return gConnectionThread->IsOnConnectionThread();
|
||||
@ -5721,6 +5726,52 @@ void LSRequestBase::ActorDestroy(ActorDestroyReason aWhy) {
|
||||
mozilla::ipc::IPCResult LSRequestBase::RecvCancel() {
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
if (MOZ_LOG_TEST(gLogger, LogLevel::Info)) {
|
||||
MOZ_LOG(gLogger, LogLevel::Info, ("LSRequestBase::RecvCancel"));
|
||||
|
||||
nsCString state;
|
||||
|
||||
switch (mState) {
|
||||
case State::Initial:
|
||||
state.AssignLiteral("Initial");
|
||||
break;
|
||||
|
||||
case State::Opening:
|
||||
state.AssignLiteral("Opening");
|
||||
break;
|
||||
|
||||
case State::Nesting:
|
||||
state.AssignLiteral("Nesting");
|
||||
break;
|
||||
|
||||
case State::SendingReadyMessage:
|
||||
state.AssignLiteral("SendingReadyMessage");
|
||||
break;
|
||||
|
||||
case State::WaitingForFinish:
|
||||
state.AssignLiteral("WaitingForFinish");
|
||||
break;
|
||||
|
||||
case State::SendingResults:
|
||||
state.AssignLiteral("SendingResults");
|
||||
break;
|
||||
|
||||
case State::Completed:
|
||||
state.AssignLiteral("Completed");
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Bad state!");
|
||||
}
|
||||
|
||||
MOZ_LOG(gLogger, LogLevel::Info, (" mState: %s", state.get()));
|
||||
}
|
||||
|
||||
const char* crashOnCancel = PR_GetEnv("LSNG_CRASH_ON_CANCEL");
|
||||
if (crashOnCancel) {
|
||||
MOZ_CRASH("LSNG: Crash on cancel.");
|
||||
}
|
||||
|
||||
IProtocol* mgr = Manager();
|
||||
if (!PBackgroundLSRequestParent::Send__delete__(this, NS_ERROR_FAILURE)) {
|
||||
return IPC_FAIL_NO_REASON(mgr);
|
||||
@ -6680,6 +6731,65 @@ void PrepareDatastoreOp::ActorDestroy(ActorDestroyReason aWhy) {
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult PrepareDatastoreOp::RecvCancel() {
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
if (MOZ_LOG_TEST(gLogger, LogLevel::Info)) {
|
||||
MOZ_LOG(gLogger, LogLevel::Info, ("PrepareDatastoreOp::RecvCancel"));
|
||||
|
||||
nsCString nestedState;
|
||||
|
||||
switch (mNestedState) {
|
||||
case NestedState::BeforeNesting:
|
||||
nestedState.AssignLiteral("BeforeNesting");
|
||||
break;
|
||||
|
||||
case NestedState::CheckExistingOperations:
|
||||
nestedState.AssignLiteral("CheckExistingOperations");
|
||||
break;
|
||||
|
||||
case NestedState::CheckClosingDatastore:
|
||||
nestedState.AssignLiteral("CheckClosingDatastore");
|
||||
break;
|
||||
|
||||
case NestedState::PreparationPending:
|
||||
nestedState.AssignLiteral("PreparationPending");
|
||||
break;
|
||||
|
||||
case NestedState::QuotaManagerPending:
|
||||
nestedState.AssignLiteral("QuotaManagerPending");
|
||||
break;
|
||||
|
||||
case NestedState::DirectoryOpenPending:
|
||||
nestedState.AssignLiteral("DirectoryOpenPending");
|
||||
break;
|
||||
|
||||
case NestedState::DatabaseWorkOpen:
|
||||
nestedState.AssignLiteral("DatabaseWorkOpen");
|
||||
break;
|
||||
|
||||
case NestedState::BeginLoadData:
|
||||
nestedState.AssignLiteral("BeginLoadData");
|
||||
break;
|
||||
|
||||
case NestedState::DatabaseWorkLoadData:
|
||||
nestedState.AssignLiteral("DatabaseWorkLoadData");
|
||||
break;
|
||||
|
||||
case NestedState::AfterNesting:
|
||||
nestedState.AssignLiteral("AfterNesting");
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Bad state!");
|
||||
}
|
||||
|
||||
MOZ_LOG(gLogger, LogLevel::Info, (" mNestedState: %s", nestedState.get()));
|
||||
}
|
||||
|
||||
return LSRequestBase::RecvCancel();
|
||||
}
|
||||
|
||||
void PrepareDatastoreOp::DirectoryLockAcquired(DirectoryLock* aLock) {
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mState == State::Nesting);
|
||||
|
@ -18,6 +18,18 @@
|
||||
#include "nsIScriptObjectPrincipal.h"
|
||||
#include "nsThread.h"
|
||||
|
||||
/**
|
||||
* Automatically cancel and abort synchronous LocalStorage requests (for example
|
||||
* datastore preparation) if they take this long. We've chosen a value that is
|
||||
* long enough that it is unlikely for the problem to be falsely triggered by
|
||||
* slow system I/O. We've also chosen a value long enough so that automated
|
||||
* tests should time out and fail if LocalStorage hangs. Also, this value is
|
||||
* long enough so that testers can notice the (content process) hang; we want to
|
||||
* know about the hangs, not hide them. On the other hand this value is less
|
||||
* than 60 seconds which is used by nsTerminator to crash a hung main process.
|
||||
*/
|
||||
#define FAILSAFE_CANCEL_SYNC_OP_MS 50000
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
@ -137,6 +149,7 @@ class RequestHelper final : public Runnable, public LSRequestChildCallback {
|
||||
State mState;
|
||||
// Control flag for the nested event loop; once set to false, the loop ends.
|
||||
bool mWaiting;
|
||||
bool mCancelled;
|
||||
|
||||
public:
|
||||
RequestHelper(LSObject* aObject, const LSRequestParams& aParams)
|
||||
@ -147,7 +160,8 @@ class RequestHelper final : public Runnable, public LSRequestChildCallback {
|
||||
mParams(aParams),
|
||||
mResultCode(NS_OK),
|
||||
mState(State::Initial),
|
||||
mWaiting(true) {}
|
||||
mWaiting(true),
|
||||
mCancelled(false) {}
|
||||
|
||||
bool IsOnOwningThread() const {
|
||||
MOZ_ASSERT(mOwningEventTarget);
|
||||
@ -1078,8 +1092,25 @@ nsresult RequestHelper::StartAndReturnResponse(LSRequestResponse& aResponse) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITimer> timer = NS_NewTimer();
|
||||
|
||||
MOZ_ALWAYS_SUCCEEDS(timer->SetTarget(mNestedEventTarget));
|
||||
|
||||
MOZ_ALWAYS_SUCCEEDS(timer->InitWithNamedFuncCallback(
|
||||
[](nsITimer* aTimer, void* aClosure) {
|
||||
auto helper = static_cast<RequestHelper*>(aClosure);
|
||||
|
||||
helper->mCancelled = true;
|
||||
},
|
||||
this, FAILSAFE_CANCEL_SYNC_OP_MS, nsITimer::TYPE_ONE_SHOT,
|
||||
"RequestHelper::StartAndReturnResponse::SpinEventLoopTimer"));
|
||||
|
||||
MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
|
||||
[&]() {
|
||||
if (mCancelled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!mWaiting) {
|
||||
return true;
|
||||
}
|
||||
@ -1094,6 +1125,8 @@ nsresult RequestHelper::StartAndReturnResponse(LSRequestResponse& aResponse) {
|
||||
return false;
|
||||
},
|
||||
thread));
|
||||
|
||||
MOZ_ALWAYS_SUCCEEDS(timer->Cancel());
|
||||
}
|
||||
|
||||
// If mWaiting is still set to true, it means that the event loop spinning
|
||||
|
@ -64,7 +64,7 @@ struct GCPolicy<T* const> : public js::InternalGCPointerPolicy<T* const> {};
|
||||
template <typename T>
|
||||
struct GCPolicy<js::HeapPtr<T>> {
|
||||
static void trace(JSTracer* trc, js::HeapPtr<T>* thingp, const char* name) {
|
||||
js::TraceEdge(trc, thingp, name);
|
||||
js::TraceNullableEdge(trc, thingp, name);
|
||||
}
|
||||
static bool needsSweep(js::HeapPtr<T>* thingp) {
|
||||
return js::gc::IsAboutToBeFinalized(thingp);
|
||||
|
@ -394,10 +394,12 @@ static const uint32_t ION_FRAME_SLACK_SIZE = 24;
|
||||
|
||||
static const uint32_t ShadowStackSpace = 0;
|
||||
|
||||
// TODO:
|
||||
// This constant needs to be updated to account for whatever near/far branching
|
||||
// strategy is used by ARM64.
|
||||
static const uint32_t JumpImmediateRange = UINT32_MAX;
|
||||
// When our only strategy for far jumps is to encode the offset directly, and
|
||||
// not insert any jump islands during assembly for even further jumps, then the
|
||||
// architecture restricts us to -2^27 .. 2^27-4, to fit into a signed 28-bit
|
||||
// value. We further reduce this range to allow the far-jump inserting code to
|
||||
// have some breathing room.
|
||||
static const uint32_t JumpImmediateRange = ((1 << 27) - (20 * 1024 * 1024));
|
||||
|
||||
static const uint32_t ABIStackAlignment = 16;
|
||||
static const uint32_t CodeAlignment = 16;
|
||||
|
Loading…
Reference in New Issue
Block a user