Merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Razvan Maries 2019-03-19 23:54:04 +02:00
commit 7c20ad9250
4 changed files with 153 additions and 8 deletions

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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;