mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-26 12:20:56 +00:00
Bug 1331209 - Part 3: Allow sending of the __delete__ message in one direction only; r=asuth
This commit is contained in:
parent
b7088851d6
commit
ea39dafe97
@ -445,7 +445,6 @@ public:
|
|||||||
mWriteParams(aWriteParams),
|
mWriteParams(aWriteParams),
|
||||||
mState(eInitial),
|
mState(eInitial),
|
||||||
mResult(JS::AsmJSCache_InternalError),
|
mResult(JS::AsmJSCache_InternalError),
|
||||||
mDeleteReceived(false),
|
|
||||||
mActorDestroyed(false),
|
mActorDestroyed(false),
|
||||||
mOpened(false)
|
mOpened(false)
|
||||||
{
|
{
|
||||||
@ -493,12 +492,17 @@ private:
|
|||||||
{
|
{
|
||||||
AssertIsOnOwningThread();
|
AssertIsOnOwningThread();
|
||||||
MOZ_ASSERT(mState == eOpened);
|
MOZ_ASSERT(mState == eOpened);
|
||||||
|
MOZ_ASSERT(mResult == JS::AsmJSCache_Success);
|
||||||
|
|
||||||
mState = eFinished;
|
mState = eFinished;
|
||||||
|
|
||||||
MOZ_ASSERT(mOpened);
|
MOZ_ASSERT(mOpened);
|
||||||
|
|
||||||
FinishOnOwningThread();
|
FinishOnOwningThread();
|
||||||
|
|
||||||
|
if (!mActorDestroyed) {
|
||||||
|
Unused << Send__delete__(this, mResult);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method is called upon any failure that prevents the eventual opening
|
// This method is called upon any failure that prevents the eventual opening
|
||||||
@ -508,6 +512,7 @@ private:
|
|||||||
{
|
{
|
||||||
AssertIsOnOwningThread();
|
AssertIsOnOwningThread();
|
||||||
MOZ_ASSERT(mState != eFinished);
|
MOZ_ASSERT(mState != eFinished);
|
||||||
|
MOZ_ASSERT(mResult != JS::AsmJSCache_Success);
|
||||||
|
|
||||||
mState = eFinished;
|
mState = eFinished;
|
||||||
|
|
||||||
@ -515,7 +520,7 @@ private:
|
|||||||
|
|
||||||
FinishOnOwningThread();
|
FinishOnOwningThread();
|
||||||
|
|
||||||
if (!mDeleteReceived && !mActorDestroyed) {
|
if (!mActorDestroyed) {
|
||||||
Unused << Send__delete__(this, mResult);
|
Unused << Send__delete__(this, mResult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -579,26 +584,6 @@ private:
|
|||||||
DirectoryLockFailed() override;
|
DirectoryLockFailed() override;
|
||||||
|
|
||||||
// IPDL methods.
|
// IPDL methods.
|
||||||
mozilla::ipc::IPCResult
|
|
||||||
Recv__delete__(const JS::AsmJSCacheResult& aResult) override
|
|
||||||
{
|
|
||||||
AssertIsOnOwningThread();
|
|
||||||
MOZ_ASSERT(mState != eFinished);
|
|
||||||
MOZ_ASSERT(!mDeleteReceived);
|
|
||||||
|
|
||||||
mDeleteReceived = true;
|
|
||||||
|
|
||||||
if (mOpened) {
|
|
||||||
Close();
|
|
||||||
} else {
|
|
||||||
Fail();
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_ASSERT(mState == eFinished);
|
|
||||||
|
|
||||||
return IPC_OK();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ActorDestroy(ActorDestroyReason why) override
|
ActorDestroy(ActorDestroyReason why) override
|
||||||
{
|
{
|
||||||
@ -624,17 +609,59 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
mozilla::ipc::IPCResult
|
mozilla::ipc::IPCResult
|
||||||
RecvSelectCacheFileToRead(const uint32_t& aModuleIndex) override
|
RecvSelectCacheFileToRead(const OpenMetadataForReadResponse& aResponse)
|
||||||
|
override
|
||||||
{
|
{
|
||||||
AssertIsOnOwningThread();
|
AssertIsOnOwningThread();
|
||||||
MOZ_ASSERT(mState == eWaitingToOpenCacheFileForRead);
|
MOZ_ASSERT(mState == eWaitingToOpenCacheFileForRead);
|
||||||
MOZ_ASSERT(mOpenMode == eOpenForRead);
|
MOZ_ASSERT(mOpenMode == eOpenForRead);
|
||||||
|
MOZ_ASSERT(!mOpened);
|
||||||
|
|
||||||
// A cache entry has been selected to open.
|
switch (aResponse.type()) {
|
||||||
|
case OpenMetadataForReadResponse::TAsmJSCacheResult: {
|
||||||
|
MOZ_ASSERT(aResponse.get_AsmJSCacheResult() != JS::AsmJSCache_Success);
|
||||||
|
|
||||||
mModuleIndex = aModuleIndex;
|
mResult = aResponse.get_AsmJSCacheResult();
|
||||||
mState = eReadyToOpenCacheFileForRead;
|
|
||||||
DispatchToIOThread();
|
// This ParentRunnable can only be held alive by the IPDL. Fail()
|
||||||
|
// clears that last reference. So we need to add a self reference here.
|
||||||
|
RefPtr<ParentRunnable> kungFuDeathGrip = this;
|
||||||
|
|
||||||
|
Fail();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case OpenMetadataForReadResponse::Tuint32_t:
|
||||||
|
// A cache entry has been selected to open.
|
||||||
|
mModuleIndex = aResponse.get_uint32_t();
|
||||||
|
|
||||||
|
mState = eReadyToOpenCacheFileForRead;
|
||||||
|
|
||||||
|
DispatchToIOThread();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
MOZ_CRASH("Should never get here!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return IPC_OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
mozilla::ipc::IPCResult
|
||||||
|
RecvClose() override
|
||||||
|
{
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
MOZ_ASSERT(mState == eOpened);
|
||||||
|
|
||||||
|
// This ParentRunnable can only be held alive by the IPDL. Close() clears
|
||||||
|
// that last reference. So we need to add a self reference here.
|
||||||
|
RefPtr<ParentRunnable> kungFuDeathGrip = this;
|
||||||
|
|
||||||
|
Close();
|
||||||
|
|
||||||
|
MOZ_ASSERT(mState == eFinished);
|
||||||
|
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
@ -675,7 +702,6 @@ private:
|
|||||||
State mState;
|
State mState;
|
||||||
JS::AsmJSCacheResult mResult;
|
JS::AsmJSCacheResult mResult;
|
||||||
|
|
||||||
bool mDeleteReceived;
|
|
||||||
bool mActorDestroyed;
|
bool mActorDestroyed;
|
||||||
bool mOpened;
|
bool mOpened;
|
||||||
};
|
};
|
||||||
@ -1021,10 +1047,6 @@ ParentRunnable::Run()
|
|||||||
|
|
||||||
mState = eOpened;
|
mState = eOpened;
|
||||||
|
|
||||||
// The entry is now open.
|
|
||||||
MOZ_ASSERT(!mOpened);
|
|
||||||
mOpened = true;
|
|
||||||
|
|
||||||
FileDescriptor::PlatformHandleType handle =
|
FileDescriptor::PlatformHandleType handle =
|
||||||
FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(mFileDesc));
|
FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(mFileDesc));
|
||||||
if (!SendOnOpenCacheFile(mFileSize, FileDescriptor(handle))) {
|
if (!SendOnOpenCacheFile(mFileSize, FileDescriptor(handle))) {
|
||||||
@ -1032,6 +1054,12 @@ ParentRunnable::Run()
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The entry is now open.
|
||||||
|
MOZ_ASSERT(!mOpened);
|
||||||
|
mOpened = true;
|
||||||
|
|
||||||
|
mResult = JS::AsmJSCache_Success;
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1291,15 +1319,16 @@ private:
|
|||||||
MOZ_ASSERT(mState == eOpening);
|
MOZ_ASSERT(mState == eOpening);
|
||||||
|
|
||||||
uint32_t moduleIndex;
|
uint32_t moduleIndex;
|
||||||
if (!FindHashMatch(aMetadata, mReadParams, &moduleIndex)) {
|
bool ok;
|
||||||
Fail(JS::AsmJSCache_InternalError);
|
if (FindHashMatch(aMetadata, mReadParams, &moduleIndex)) {
|
||||||
Send__delete__(this, JS::AsmJSCache_InternalError);
|
ok = SendSelectCacheFileToRead(moduleIndex);
|
||||||
return IPC_OK();
|
} else {
|
||||||
|
ok = SendSelectCacheFileToRead(JS::AsmJSCache_InternalError);
|
||||||
}
|
}
|
||||||
|
if (!ok) {
|
||||||
if (!SendSelectCacheFileToRead(moduleIndex)) {
|
|
||||||
return IPC_FAIL_NO_REASON(this);
|
return IPC_FAIL_NO_REASON(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1327,9 +1356,20 @@ private:
|
|||||||
Recv__delete__(const JS::AsmJSCacheResult& aResult) override
|
Recv__delete__(const JS::AsmJSCacheResult& aResult) override
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
MOZ_ASSERT(mState == eOpening);
|
MOZ_ASSERT(mState == eOpening || mState == eFinishing);
|
||||||
|
MOZ_ASSERT_IF(mState == eOpening, aResult != JS::AsmJSCache_Success);
|
||||||
|
MOZ_ASSERT_IF(mState == eFinishing, aResult == JS::AsmJSCache_Success);
|
||||||
|
|
||||||
Fail(aResult);
|
if (mState == eOpening) {
|
||||||
|
Fail(aResult);
|
||||||
|
} else {
|
||||||
|
// Match the AddRef in BlockUntilOpen(). The IPDL still holds an
|
||||||
|
// outstanding ref which will keep 'this' alive until ActorDestroy()
|
||||||
|
// is executed.
|
||||||
|
Release();
|
||||||
|
|
||||||
|
mState = eFinished;
|
||||||
|
}
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1395,6 +1435,7 @@ private:
|
|||||||
eOpening, // Waiting for the parent process to respond
|
eOpening, // Waiting for the parent process to respond
|
||||||
eOpened, // Parent process opened the entry and sent it back
|
eOpened, // Parent process opened the entry and sent it back
|
||||||
eClosing, // Waiting to be dispatched to the main thread to Send__delete__
|
eClosing, // Waiting to be dispatched to the main thread to Send__delete__
|
||||||
|
eFinishing, // Waiting for the parent process to close
|
||||||
eFinished // Terminal state
|
eFinished // Terminal state
|
||||||
};
|
};
|
||||||
State mState;
|
State mState;
|
||||||
@ -1454,27 +1495,31 @@ ChildRunnable::Run()
|
|||||||
|
|
||||||
// Per FileDescriptorHolder::Finish()'s comment, call before
|
// Per FileDescriptorHolder::Finish()'s comment, call before
|
||||||
// releasing the directory lock (which happens in the parent upon receipt
|
// releasing the directory lock (which happens in the parent upon receipt
|
||||||
// of the Send__delete__ message).
|
// of the Close message).
|
||||||
FileDescriptorHolder::Finish();
|
FileDescriptorHolder::Finish();
|
||||||
|
|
||||||
MOZ_ASSERT(mOpened);
|
MOZ_ASSERT(mOpened);
|
||||||
mOpened = false;
|
mOpened = false;
|
||||||
|
|
||||||
// Match the AddRef in BlockUntilOpen(). The main thread event loop still
|
if (mActorDestroyed) {
|
||||||
// holds an outstanding ref which will keep 'this' alive until returning to
|
// Match the AddRef in BlockUntilOpen(). The main thread event loop
|
||||||
// the event loop.
|
// still holds an outstanding ref which will keep 'this' alive until
|
||||||
Release();
|
// returning to the event loop.
|
||||||
|
Release();
|
||||||
|
|
||||||
if (!mActorDestroyed) {
|
mState = eFinished;
|
||||||
Unused << Send__delete__(this, JS::AsmJSCache_Success);
|
} else {
|
||||||
|
Unused << SendClose();
|
||||||
|
|
||||||
|
mState = eFinishing;
|
||||||
}
|
}
|
||||||
|
|
||||||
mState = eFinished;
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
case eOpening:
|
case eOpening:
|
||||||
case eOpened:
|
case eOpened:
|
||||||
|
case eFinishing:
|
||||||
case eFinished: {
|
case eFinished: {
|
||||||
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Shouldn't Run() in this state");
|
MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Shouldn't Run() in this state");
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,12 @@ namespace mozilla {
|
|||||||
namespace dom {
|
namespace dom {
|
||||||
namespace asmjscache {
|
namespace asmjscache {
|
||||||
|
|
||||||
|
union OpenMetadataForReadResponse
|
||||||
|
{
|
||||||
|
AsmJSCacheResult;
|
||||||
|
uint32_t;
|
||||||
|
};
|
||||||
|
|
||||||
protocol PAsmJSCacheEntry
|
protocol PAsmJSCacheEntry
|
||||||
{
|
{
|
||||||
manager PBackground;
|
manager PBackground;
|
||||||
@ -21,14 +27,24 @@ protocol PAsmJSCacheEntry
|
|||||||
child:
|
child:
|
||||||
async OnOpenMetadataForRead(Metadata metadata);
|
async OnOpenMetadataForRead(Metadata metadata);
|
||||||
parent:
|
parent:
|
||||||
async SelectCacheFileToRead(uint32_t moduleIndex);
|
async SelectCacheFileToRead(OpenMetadataForReadResponse response);
|
||||||
|
|
||||||
child:
|
child:
|
||||||
// Once the cache file has been opened, the child is notified and sent an
|
// Once the cache file has been opened, the child is notified and sent an
|
||||||
// open file descriptor.
|
// open file descriptor.
|
||||||
async OnOpenCacheFile(int64_t fileSize, FileDescriptor fileDesc);
|
async OnOpenCacheFile(int64_t fileSize, FileDescriptor fileDesc);
|
||||||
|
|
||||||
both:
|
parent:
|
||||||
|
// When the child process is done with the cache entry, the parent process
|
||||||
|
// is notified (via Close).
|
||||||
|
async Close();
|
||||||
|
|
||||||
|
child:
|
||||||
|
// When there's an error during the opening phase, the child process is
|
||||||
|
// notified (via __delete__) and sent an error result.
|
||||||
|
// When the parent process receives the Close message, it closes the cache
|
||||||
|
// entry on the parent side and the child is notified (via __delete__).
|
||||||
|
// The protocol is destroyed in both cases.
|
||||||
async __delete__(AsmJSCacheResult result);
|
async __delete__(AsmJSCacheResult result);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user