зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1346987 - Part 1: Introduce the asynchronous ContentChild::AsyncOpenAnonymousTemporaryFile() API; r=billm
This commit is contained in:
Родитель
32cff5d448
Коммит
4482865081
|
@ -198,6 +198,7 @@
|
|||
#include "gfxPlatform.h"
|
||||
#include "nscore.h" // for NS_FREE_PERMANENT_DATA
|
||||
#include "VRManagerChild.h"
|
||||
#include "private/pprio.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK
|
||||
#include "nsAppRunner.h"
|
||||
|
@ -3222,5 +3223,43 @@ ContentChild::RecvParentActivated(PBrowserChild* aTab, const bool& aActivated)
|
|||
return tab->RecvParentActivated(aActivated);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
ContentChild::RecvProvideAnonymousTemporaryFile(const uint64_t& aID,
|
||||
const FileDescOrError& aFDOrError)
|
||||
{
|
||||
nsAutoPtr<AnonymousTemporaryFileCallback> callback;
|
||||
mPendingAnonymousTemporaryFiles.RemoveAndForget(aID, callback);
|
||||
MOZ_ASSERT(callback);
|
||||
|
||||
PRFileDesc* prfile = nullptr;
|
||||
if (aFDOrError.type() == FileDescOrError::Tnsresult) {
|
||||
DebugOnly<nsresult> rv = aFDOrError.get_nsresult();
|
||||
MOZ_ASSERT(NS_FAILED(rv));
|
||||
} else {
|
||||
auto rawFD = aFDOrError.get_FileDescriptor().ClonePlatformHandle();
|
||||
prfile = PR_ImportFile(PROsfd(rawFD.release()));
|
||||
}
|
||||
(*callback)(prfile);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
nsresult
|
||||
ContentChild::AsyncOpenAnonymousTemporaryFile(AnonymousTemporaryFileCallback aCallback)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
static uint64_t id = 0;
|
||||
auto newID = id++;
|
||||
if (!SendRequestAnonymousTemporaryFile(newID)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Remember the association with the callback.
|
||||
MOZ_ASSERT(!mPendingAnonymousTemporaryFiles.Get(newID));
|
||||
mPendingAnonymousTemporaryFiles.LookupOrAdd(newID, aCallback);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -586,6 +586,9 @@ public:
|
|||
const StructuredCloneData& aInitialData,
|
||||
nsTArray<LookAndFeelInt>&& aLookAndFeelIntCache) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvProvideAnonymousTemporaryFile(const uint64_t& aID, const FileDescOrError& aFD) override;
|
||||
|
||||
#if defined(XP_WIN) && defined(ACCESSIBILITY)
|
||||
bool
|
||||
SendGetA11yContentId();
|
||||
|
@ -628,6 +631,9 @@ public:
|
|||
const Optional<int64_t>& aLastModified,
|
||||
bool aExistenceCheck, bool aIsFromNsIFile);
|
||||
|
||||
typedef std::function<void(PRFileDesc*)> AnonymousTemporaryFileCallback;
|
||||
nsresult AsyncOpenAnonymousTemporaryFile(AnonymousTemporaryFileCallback aCallback);
|
||||
|
||||
private:
|
||||
static void ForceKillTimerCallback(nsITimer* aTimer, void* aClosure);
|
||||
void StartForceKillTimer();
|
||||
|
@ -696,6 +702,9 @@ private:
|
|||
// These items are removed when RecvFileCreationResponse is received.
|
||||
nsRefPtrHashtable<nsIDHashKey, FileCreatorHelper> mFileCreationPending;
|
||||
|
||||
|
||||
nsClassHashtable<nsUint64HashKey, AnonymousTemporaryFileCallback> mPendingAnonymousTemporaryFiles;
|
||||
|
||||
bool mShuttingDown;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(ContentChild);
|
||||
|
|
|
@ -4087,6 +4087,80 @@ ContentParent::RecvBackUpXResources(const FileDescriptor& aXSocketFd)
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
class AnonymousTemporaryFileRequestor final : public Runnable
|
||||
{
|
||||
public:
|
||||
AnonymousTemporaryFileRequestor(ContentParent* aCP, const uint64_t& aID)
|
||||
: mCP(aCP)
|
||||
, mID(aID)
|
||||
, mRv(NS_OK)
|
||||
, mPRFD(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() override
|
||||
{
|
||||
if (NS_IsMainThread()) {
|
||||
FileDescOrError result;
|
||||
if (NS_WARN_IF(NS_FAILED(mRv))) {
|
||||
// Returning false will kill the child process; instead
|
||||
// propagate the error and let the child handle it.
|
||||
result = mRv;
|
||||
} else {
|
||||
result = FileDescriptor(FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(mPRFD)));
|
||||
// The FileDescriptor object owns a duplicate of the file handle; we
|
||||
// must close the original (and clean up the NSPR descriptor).
|
||||
PR_Close(mPRFD);
|
||||
}
|
||||
Unused << mCP->SendProvideAnonymousTemporaryFile(mID, result);
|
||||
// It's important to release this reference while wr're on the main thread!
|
||||
mCP = nullptr;
|
||||
} else {
|
||||
mRv = NS_OpenAnonymousTemporaryFile(&mPRFD);
|
||||
NS_DispatchToMainThread(this);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<ContentParent> mCP;
|
||||
uint64_t mID;
|
||||
nsresult mRv;
|
||||
PRFileDesc* mPRFD;
|
||||
};
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
ContentParent::RecvRequestAnonymousTemporaryFile(const uint64_t& aID)
|
||||
{
|
||||
// Make sure to send a callback to the child if we bail out early.
|
||||
nsresult rv = NS_OK;
|
||||
RefPtr<ContentParent> self(this);
|
||||
auto autoNotifyChildOnError = MakeScopeExit([&]() {
|
||||
if (NS_FAILED(rv)) {
|
||||
FileDescOrError result(rv);
|
||||
Unused << self->SendProvideAnonymousTemporaryFile(aID, result);
|
||||
}
|
||||
});
|
||||
|
||||
// We use a helper runnable to open the anonymous temporary file on the IO
|
||||
// thread. The same runnable will call us back on the main thread when the
|
||||
// file has been opened.
|
||||
nsCOMPtr<nsIEventTarget> target
|
||||
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv);
|
||||
if (!target) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
rv = target->Dispatch(new AnonymousTemporaryFileRequestor(this, aID),
|
||||
NS_DISPATCH_NORMAL);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
rv = NS_OK;
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
ContentParent::RecvOpenAnonymousTemporaryFile(FileDescOrError *aFD)
|
||||
{
|
||||
|
|
|
@ -1058,6 +1058,9 @@ private:
|
|||
virtual mozilla::ipc::IPCResult
|
||||
RecvBackUpXResources(const FileDescriptor& aXSocketFd) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvRequestAnonymousTemporaryFile(const uint64_t& aID) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvOpenAnonymousTemporaryFile(FileDescOrError* aFD) override;
|
||||
|
||||
|
|
|
@ -591,6 +591,8 @@ child:
|
|||
|
||||
async PParentToChildStream();
|
||||
|
||||
async ProvideAnonymousTemporaryFile(uint64_t aID, FileDescOrError aFD);
|
||||
|
||||
parent:
|
||||
async InitBackground(Endpoint<PBackgroundParent> aEndpoint);
|
||||
|
||||
|
@ -872,6 +874,8 @@ parent:
|
|||
*/
|
||||
async BackUpXResources(FileDescriptor aXSocketFd);
|
||||
|
||||
async RequestAnonymousTemporaryFile(uint64_t aID);
|
||||
|
||||
sync OpenAnonymousTemporaryFile() returns (FileDescOrError aFD);
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче