зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 3 changesets (bug 1346987) for media, blob, and temporaryfile failures
CLOSED TREE Backed out changeset d24fa1b4553b (bug 1346987) Backed out changeset 34701b9ed4ba (bug 1346987) Backed out changeset f24f4fdc5cc8 (bug 1346987)
This commit is contained in:
Родитель
f6e6e9870e
Коммит
dd44ef2360
|
@ -111,7 +111,6 @@ public:
|
||||||
: mBlobStorage(aBlobStorage)
|
: mBlobStorage(aBlobStorage)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
|
||||||
MOZ_ASSERT(aBlobStorage);
|
MOZ_ASSERT(aBlobStorage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,11 +118,14 @@ public:
|
||||||
Run() override
|
Run() override
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!NS_IsMainThread());
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
MOZ_ASSERT(XRE_IsParentProcess());
|
|
||||||
|
|
||||||
PRFileDesc* tempFD = nullptr;
|
PRFileDesc* tempFD = nullptr;
|
||||||
nsresult rv = NS_OpenAnonymousTemporaryFile(&tempFD);
|
nsresult rv = NS_OpenAnonymousTemporaryFile(&tempFD);
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
// In sandboxed context we are not allowed to create temporary files, but
|
||||||
|
// this doesn't mean that BlobStorage should fail. We can continue to
|
||||||
|
// store data in memory. We don't change the storageType so that we don't
|
||||||
|
// try to create a temporary file again.
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,20 +534,9 @@ MutableBlobStorage::ShouldBeTemporaryStorage(uint64_t aSize) const
|
||||||
nsresult
|
nsresult
|
||||||
MutableBlobStorage::MaybeCreateTemporaryFile()
|
MutableBlobStorage::MaybeCreateTemporaryFile()
|
||||||
{
|
{
|
||||||
if (XRE_IsParentProcess()) {
|
nsresult rv = DispatchToIOThread(new CreateTemporaryFileRunnable(this));
|
||||||
nsresult rv = DispatchToIOThread(new CreateTemporaryFileRunnable(this));
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
return rv;
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
RefPtr<MutableBlobStorage> self(this);
|
|
||||||
ContentChild::GetSingleton()->
|
|
||||||
AsyncOpenAnonymousTemporaryFile([self](PRFileDesc* prfile) {
|
|
||||||
if (prfile) {
|
|
||||||
// The ownership of the prfile is moved to the FileCreatedRunnable.
|
|
||||||
NS_DispatchToMainThread(new FileCreatedRunnable(self, prfile));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mStorageState = eWaitingForTemporaryFile;
|
mStorageState = eWaitingForTemporaryFile;
|
||||||
|
|
|
@ -198,7 +198,6 @@
|
||||||
#include "gfxPlatform.h"
|
#include "gfxPlatform.h"
|
||||||
#include "nscore.h" // for NS_FREE_PERMANENT_DATA
|
#include "nscore.h" // for NS_FREE_PERMANENT_DATA
|
||||||
#include "VRManagerChild.h"
|
#include "VRManagerChild.h"
|
||||||
#include "private/pprio.h"
|
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_GTK
|
#ifdef MOZ_WIDGET_GTK
|
||||||
#include "nsAppRunner.h"
|
#include "nsAppRunner.h"
|
||||||
|
@ -3223,42 +3222,5 @@ ContentChild::RecvParentActivated(PBrowserChild* aTab, const bool& aActivated)
|
||||||
return tab->RecvParentActivated(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;
|
|
||||||
if (!SendRequestAnonymousTemporaryFile(id++)) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remember the association with the callback.
|
|
||||||
MOZ_ASSERT(!mPendingAnonymousTemporaryFiles.Get(id));
|
|
||||||
mPendingAnonymousTemporaryFiles.LookupOrAdd(id, aCallback);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -586,9 +586,6 @@ public:
|
||||||
const StructuredCloneData& aInitialData,
|
const StructuredCloneData& aInitialData,
|
||||||
nsTArray<LookAndFeelInt>&& aLookAndFeelIntCache) override;
|
nsTArray<LookAndFeelInt>&& aLookAndFeelIntCache) override;
|
||||||
|
|
||||||
virtual mozilla::ipc::IPCResult
|
|
||||||
RecvProvideAnonymousTemporaryFile(const uint64_t& aID, const FileDescOrError& aFD) override;
|
|
||||||
|
|
||||||
#if defined(XP_WIN) && defined(ACCESSIBILITY)
|
#if defined(XP_WIN) && defined(ACCESSIBILITY)
|
||||||
bool
|
bool
|
||||||
SendGetA11yContentId();
|
SendGetA11yContentId();
|
||||||
|
@ -631,9 +628,6 @@ public:
|
||||||
const Optional<int64_t>& aLastModified,
|
const Optional<int64_t>& aLastModified,
|
||||||
bool aExistenceCheck, bool aIsFromNsIFile);
|
bool aExistenceCheck, bool aIsFromNsIFile);
|
||||||
|
|
||||||
typedef std::function<void(PRFileDesc*)> AnonymousTemporaryFileCallback;
|
|
||||||
nsresult AsyncOpenAnonymousTemporaryFile(AnonymousTemporaryFileCallback aCallback);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void ForceKillTimerCallback(nsITimer* aTimer, void* aClosure);
|
static void ForceKillTimerCallback(nsITimer* aTimer, void* aClosure);
|
||||||
void StartForceKillTimer();
|
void StartForceKillTimer();
|
||||||
|
@ -702,8 +696,6 @@ private:
|
||||||
// These items are removed when RecvFileCreationResponse is received.
|
// These items are removed when RecvFileCreationResponse is received.
|
||||||
nsRefPtrHashtable<nsIDHashKey, FileCreatorHelper> mFileCreationPending;
|
nsRefPtrHashtable<nsIDHashKey, FileCreatorHelper> mFileCreationPending;
|
||||||
|
|
||||||
nsClassHashtable<nsUint64HashKey, AnonymousTemporaryFileCallback> mPendingAnonymousTemporaryFiles;
|
|
||||||
|
|
||||||
bool mShuttingDown;
|
bool mShuttingDown;
|
||||||
|
|
||||||
DISALLOW_EVIL_CONSTRUCTORS(ContentChild);
|
DISALLOW_EVIL_CONSTRUCTORS(ContentChild);
|
||||||
|
|
|
@ -4077,78 +4077,6 @@ ContentParent::RecvBackUpXResources(const FileDescriptor& aXSocketFd)
|
||||||
return IPC_OK();
|
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);
|
|
||||||
} 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
|
mozilla::ipc::IPCResult
|
||||||
ContentParent::RecvOpenAnonymousTemporaryFile(FileDescOrError *aFD)
|
ContentParent::RecvOpenAnonymousTemporaryFile(FileDescOrError *aFD)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1041,9 +1041,6 @@ private:
|
||||||
virtual mozilla::ipc::IPCResult
|
virtual mozilla::ipc::IPCResult
|
||||||
RecvBackUpXResources(const FileDescriptor& aXSocketFd) override;
|
RecvBackUpXResources(const FileDescriptor& aXSocketFd) override;
|
||||||
|
|
||||||
virtual mozilla::ipc::IPCResult
|
|
||||||
RecvRequestAnonymousTemporaryFile(const uint64_t& aID) override;
|
|
||||||
|
|
||||||
virtual mozilla::ipc::IPCResult
|
virtual mozilla::ipc::IPCResult
|
||||||
RecvOpenAnonymousTemporaryFile(FileDescOrError* aFD) override;
|
RecvOpenAnonymousTemporaryFile(FileDescOrError* aFD) override;
|
||||||
|
|
||||||
|
|
|
@ -591,8 +591,6 @@ child:
|
||||||
|
|
||||||
async PParentToChildStream();
|
async PParentToChildStream();
|
||||||
|
|
||||||
async ProvideAnonymousTemporaryFile(uint64_t aID, FileDescOrError aFD);
|
|
||||||
|
|
||||||
parent:
|
parent:
|
||||||
async InitBackground(Endpoint<PBackgroundParent> aEndpoint);
|
async InitBackground(Endpoint<PBackgroundParent> aEndpoint);
|
||||||
|
|
||||||
|
@ -874,8 +872,6 @@ parent:
|
||||||
*/
|
*/
|
||||||
async BackUpXResources(FileDescriptor aXSocketFd);
|
async BackUpXResources(FileDescriptor aXSocketFd);
|
||||||
|
|
||||||
async RequestAnonymousTemporaryFile(uint64_t aID);
|
|
||||||
|
|
||||||
sync OpenAnonymousTemporaryFile() returns (FileDescOrError aFD);
|
sync OpenAnonymousTemporaryFile() returns (FileDescOrError aFD);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -5,21 +5,15 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "EncodedBufferCache.h"
|
#include "EncodedBufferCache.h"
|
||||||
#include "prio.h"
|
|
||||||
#include "nsAnonymousTemporaryFile.h"
|
|
||||||
#include "mozilla/Monitor.h"
|
|
||||||
#include "mozilla/dom/ContentChild.h"
|
|
||||||
#include "mozilla/dom/File.h"
|
#include "mozilla/dom/File.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsAnonymousTemporaryFile.h"
|
||||||
#include "nsXULAppAPI.h"
|
#include "prio.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
void
|
void
|
||||||
EncodedBufferCache::AppendBuffer(nsTArray<uint8_t> & aBuf)
|
EncodedBufferCache::AppendBuffer(nsTArray<uint8_t> & aBuf)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!NS_IsMainThread());
|
|
||||||
|
|
||||||
MutexAutoLock lock(mMutex);
|
MutexAutoLock lock(mMutex);
|
||||||
mDataSize += aBuf.Length();
|
mDataSize += aBuf.Length();
|
||||||
|
|
||||||
|
@ -29,40 +23,10 @@ EncodedBufferCache::AppendBuffer(nsTArray<uint8_t> & aBuf)
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
PRFileDesc* tempFD = nullptr;
|
PRFileDesc* tempFD = nullptr;
|
||||||
{
|
{
|
||||||
// Release the mMutex because of the sync dispatch to the main thread.
|
// Release the mMutex because there is a sync dispatch to mainthread in
|
||||||
|
// NS_OpenAnonymousTemporaryFile.
|
||||||
MutexAutoUnlock unlock(mMutex);
|
MutexAutoUnlock unlock(mMutex);
|
||||||
if (XRE_IsParentProcess()) {
|
rv = NS_OpenAnonymousTemporaryFile(&tempFD);
|
||||||
// In case we are in the parent process, do a synchronous I/O here to open a
|
|
||||||
// temporary file.
|
|
||||||
rv = NS_OpenAnonymousTemporaryFile(&tempFD);
|
|
||||||
} else {
|
|
||||||
// In case we are in the child process, we don't have access to open a file
|
|
||||||
// directly due to sandbox restrictions, so we need to ask the parent process
|
|
||||||
// to do that for us. In order to initiate the IPC, we need to first go to
|
|
||||||
// the main thread. This is done by dispatching a runnable to the main thread.
|
|
||||||
// From there, we start an asynchronous IPC, and we block the current thread
|
|
||||||
// using a monitor while this async work is in progress. When we receive the
|
|
||||||
// resulting file descriptor from the parent process, we notify the monitor
|
|
||||||
// and unblock the current thread and continue.
|
|
||||||
typedef dom::ContentChild::AnonymousTemporaryFileCallback
|
|
||||||
AnonymousTemporaryFileCallback;
|
|
||||||
Monitor monitor("EncodeBufferCache::AppendBuffer");
|
|
||||||
RefPtr<dom::ContentChild> cc = dom::ContentChild::GetSingleton();
|
|
||||||
nsCOMPtr<nsIRunnable> runnable =
|
|
||||||
NewRunnableMethod<AnonymousTemporaryFileCallback>(cc,
|
|
||||||
&dom::ContentChild::AsyncOpenAnonymousTemporaryFile,
|
|
||||||
[&](PRFileDesc* aFile) {
|
|
||||||
rv = aFile ? NS_OK : NS_ERROR_FAILURE;
|
|
||||||
tempFD = aFile;
|
|
||||||
MonitorAutoLock lock(monitor);
|
|
||||||
lock.Notify();
|
|
||||||
});
|
|
||||||
rv = NS_DispatchToMainThread(runnable);
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
MonitorAutoLock lock(monitor);
|
|
||||||
lock.Wait();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!NS_FAILED(rv)) {
|
if (!NS_FAILED(rv)) {
|
||||||
// Check the mDataSize again since we release the mMutex before.
|
// Check the mDataSize again since we release the mMutex before.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче