зеркало из https://github.com/mozilla/gecko-dev.git
Bug 961049 - Part 6: Quota Manager on PBackground cache changes; r=bkelly
This commit is contained in:
Родитель
e524e8e0e4
Коммит
945dffa14f
|
@ -132,7 +132,7 @@ public:
|
|||
NS_ASSERT_OWNINGTHREAD(QuotaInitRunnable);
|
||||
MOZ_ASSERT(mState == STATE_INIT);
|
||||
|
||||
mState = STATE_OPEN_DIRECTORY;
|
||||
mState = STATE_GET_INFO;
|
||||
nsresult rv = NS_DispatchToMainThread(this, nsIThread::DISPATCH_NORMAL);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
mState = STATE_COMPLETE;
|
||||
|
@ -149,6 +149,8 @@ public:
|
|||
mInitAction->CancelOnInitiatingThread();
|
||||
}
|
||||
|
||||
void OpenDirectory();
|
||||
|
||||
// OpenDirectoryListener methods
|
||||
virtual void
|
||||
DirectoryLockAcquired(DirectoryLock* aLock) override;
|
||||
|
@ -195,6 +197,8 @@ private:
|
|||
enum State
|
||||
{
|
||||
STATE_INIT,
|
||||
STATE_GET_INFO,
|
||||
STATE_CREATE_QUOTA_MANAGER,
|
||||
STATE_OPEN_DIRECTORY,
|
||||
STATE_WAIT_FOR_DIRECTORY_LOCK,
|
||||
STATE_ENSURE_ORIGIN_INITIALIZED,
|
||||
|
@ -234,7 +238,7 @@ private:
|
|||
nsCOMPtr<nsIThread> mInitiatingThread;
|
||||
nsresult mResult;
|
||||
QuotaInfo mQuotaInfo;
|
||||
nsMainThreadPtrHandle<DirectoryLock> mDirectoryLock;
|
||||
RefPtr<DirectoryLock> mDirectoryLock;
|
||||
State mState;
|
||||
Atomic<bool> mCanceled;
|
||||
|
||||
|
@ -243,14 +247,35 @@ public:
|
|||
NS_DECL_NSIRUNNABLE
|
||||
};
|
||||
|
||||
void
|
||||
Context::QuotaInitRunnable::OpenDirectory()
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(QuotaInitRunnable);
|
||||
MOZ_ASSERT(mState == STATE_CREATE_QUOTA_MANAGER ||
|
||||
mState == STATE_OPEN_DIRECTORY);
|
||||
MOZ_ASSERT(QuotaManager::Get());
|
||||
|
||||
// QuotaManager::OpenDirectory() will hold a reference to us as
|
||||
// a listener. We will then get DirectoryLockAcquired() on the owning
|
||||
// thread when it is safe to access our storage directory.
|
||||
mState = STATE_WAIT_FOR_DIRECTORY_LOCK;
|
||||
QuotaManager::Get()->OpenDirectory(PERSISTENCE_TYPE_DEFAULT,
|
||||
mQuotaInfo.mGroup,
|
||||
mQuotaInfo.mOrigin,
|
||||
mQuotaInfo.mIsApp,
|
||||
quota::Client::DOMCACHE,
|
||||
/* aExclusive */ false,
|
||||
this);
|
||||
}
|
||||
|
||||
void
|
||||
Context::QuotaInitRunnable::DirectoryLockAcquired(DirectoryLock* aLock)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
NS_ASSERT_OWNINGTHREAD(QuotaInitRunnable);
|
||||
MOZ_ASSERT(mState == STATE_WAIT_FOR_DIRECTORY_LOCK);
|
||||
MOZ_ASSERT(!mDirectoryLock);
|
||||
|
||||
mDirectoryLock = new nsMainThreadPtrHolder<DirectoryLock>(aLock);
|
||||
mDirectoryLock = aLock;
|
||||
|
||||
if (mCanceled) {
|
||||
Complete(NS_ERROR_ABORT);
|
||||
|
@ -271,7 +296,7 @@ Context::QuotaInitRunnable::DirectoryLockAcquired(DirectoryLock* aLock)
|
|||
void
|
||||
Context::QuotaInitRunnable::DirectoryLockFailed()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
NS_ASSERT_OWNINGTHREAD(QuotaInitRunnable);
|
||||
MOZ_ASSERT(mState == STATE_WAIT_FOR_DIRECTORY_LOCK);
|
||||
MOZ_ASSERT(!mDirectoryLock);
|
||||
|
||||
|
@ -290,13 +315,23 @@ NS_IMPL_ISUPPORTS(mozilla::dom::cache::Context::QuotaInitRunnable, nsIRunnable);
|
|||
// +-------+-------+ |
|
||||
// | |
|
||||
// +----------v-----------+ |
|
||||
// | OpenDirectory | Resolve(error) |
|
||||
// | GetInfo | Resolve(error) |
|
||||
// | (Main Thread) +-----------------+
|
||||
// +----------+-----------+ |
|
||||
// | |
|
||||
// +----------v-----------+ |
|
||||
// | CreateQuotaManager | Resolve(error) |
|
||||
// | (Orig Thread) +-----------------+
|
||||
// +----------+-----------+ |
|
||||
// | |
|
||||
// +----------v-----------+ |
|
||||
// | OpenDirectory | Resolve(error) |
|
||||
// | (Orig Thread) +-----------------+
|
||||
// +----------+-----------+ |
|
||||
// | |
|
||||
// +----------v-----------+ |
|
||||
// | WaitForDirectoryLock | Resolve(error) |
|
||||
// | (Main Thread) +-----------------+
|
||||
// | (Orig Thread) +-----------------+
|
||||
// +----------+-----------+ |
|
||||
// | |
|
||||
// +----------v------------+ |
|
||||
|
@ -330,43 +365,61 @@ Context::QuotaInitRunnable::Run()
|
|||
|
||||
switch(mState) {
|
||||
// -----------------------------------
|
||||
case STATE_OPEN_DIRECTORY:
|
||||
case STATE_GET_INFO:
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mCanceled) {
|
||||
resolver->Resolve(NS_ERROR_ABORT);
|
||||
break;
|
||||
}
|
||||
|
||||
RefPtr<ManagerId> managerId = mManager->GetManagerId();
|
||||
nsCOMPtr<nsIPrincipal> principal = managerId->Principal();
|
||||
nsresult rv = QuotaManager::GetInfoFromPrincipal(principal,
|
||||
&mQuotaInfo.mGroup,
|
||||
&mQuotaInfo.mOrigin,
|
||||
&mQuotaInfo.mIsApp);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
resolver->Resolve(rv);
|
||||
break;
|
||||
}
|
||||
|
||||
mState = STATE_CREATE_QUOTA_MANAGER;
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
|
||||
mInitiatingThread->Dispatch(this, nsIThread::DISPATCH_NORMAL)));
|
||||
break;
|
||||
}
|
||||
// ----------------------------------
|
||||
case STATE_CREATE_QUOTA_MANAGER:
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(QuotaInitRunnable);
|
||||
|
||||
if (mCanceled || QuotaManager::IsShuttingDown()) {
|
||||
resolver->Resolve(NS_ERROR_ABORT);
|
||||
break;
|
||||
}
|
||||
|
||||
QuotaManager* qm = QuotaManager::GetOrCreate();
|
||||
if (!qm) {
|
||||
if (QuotaManager::Get()) {
|
||||
OpenDirectory();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mState = STATE_OPEN_DIRECTORY;
|
||||
QuotaManager::GetOrCreate(this);
|
||||
break;
|
||||
}
|
||||
// ----------------------------------
|
||||
case STATE_OPEN_DIRECTORY:
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(QuotaInitRunnable);
|
||||
|
||||
if (NS_WARN_IF(!QuotaManager::Get())) {
|
||||
resolver->Resolve(NS_ERROR_FAILURE);
|
||||
break;
|
||||
}
|
||||
|
||||
RefPtr<ManagerId> managerId = mManager->GetManagerId();
|
||||
nsCOMPtr<nsIPrincipal> principal = managerId->Principal();
|
||||
nsresult rv = qm->GetInfoFromPrincipal(principal,
|
||||
&mQuotaInfo.mGroup,
|
||||
&mQuotaInfo.mOrigin,
|
||||
&mQuotaInfo.mIsApp);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
resolver->Resolve(rv);
|
||||
break;
|
||||
}
|
||||
|
||||
// QuotaManager::OpenDirectory() will hold a reference to us as
|
||||
// a listener. We will then get DirectoryLockAcquired() on the main
|
||||
// thread when it is safe to access our storage directory.
|
||||
mState = STATE_WAIT_FOR_DIRECTORY_LOCK;
|
||||
qm->OpenDirectory(PERSISTENCE_TYPE_DEFAULT,
|
||||
mQuotaInfo.mGroup,
|
||||
mQuotaInfo.mOrigin,
|
||||
mQuotaInfo.mIsApp,
|
||||
quota::Client::DOMCACHE,
|
||||
/* aExclusive */ false,
|
||||
this);
|
||||
OpenDirectory();
|
||||
break;
|
||||
}
|
||||
// ----------------------------------
|
||||
|
@ -425,7 +478,7 @@ Context::QuotaInitRunnable::Run()
|
|||
{
|
||||
NS_ASSERT_OWNINGTHREAD(QuotaInitRunnable);
|
||||
mInitAction->CompleteOnInitiatingThread(mResult);
|
||||
mContext->OnQuotaInit(mResult, mQuotaInfo, mDirectoryLock);
|
||||
mContext->OnQuotaInit(mResult, mQuotaInfo, mDirectoryLock.forget());
|
||||
mState = STATE_COMPLETE;
|
||||
|
||||
// Explicitly cleanup here as the destructor could fire on any of
|
||||
|
@ -987,7 +1040,7 @@ Context::DispatchAction(Action* aAction, bool aDoomData)
|
|||
|
||||
void
|
||||
Context::OnQuotaInit(nsresult aRv, const QuotaInfo& aQuotaInfo,
|
||||
nsMainThreadPtrHandle<DirectoryLock>& aDirectoryLock)
|
||||
already_AddRefed<DirectoryLock> aDirectoryLock)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(Context);
|
||||
|
||||
|
|
|
@ -190,7 +190,8 @@ private:
|
|||
void Start();
|
||||
void DispatchAction(Action* aAction, bool aDoomData = false);
|
||||
void OnQuotaInit(nsresult aRv, const QuotaInfo& aQuotaInfo,
|
||||
nsMainThreadPtrHandle<DirectoryLock>& aDirectoryLock);
|
||||
already_AddRefed<DirectoryLock> aDirectoryLock);
|
||||
|
||||
|
||||
already_AddRefed<ThreadsafeHandle>
|
||||
CreateThreadsafeHandle();
|
||||
|
@ -221,7 +222,7 @@ private:
|
|||
// when ThreadsafeHandle::AllowToClose() is called.
|
||||
RefPtr<ThreadsafeHandle> mThreadsafeHandle;
|
||||
|
||||
nsMainThreadPtrHandle<DirectoryLock> mDirectoryLock;
|
||||
RefPtr<DirectoryLock> mDirectoryLock;
|
||||
RefPtr<Context> mNextContext;
|
||||
|
||||
public:
|
||||
|
|
|
@ -242,55 +242,61 @@ public:
|
|||
}
|
||||
|
||||
static void
|
||||
StartAbortOnMainThread(const nsACString& aOrigin)
|
||||
Abort(const nsACString& aOrigin)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mozilla::ipc::AssertIsOnBackgroundThread();
|
||||
|
||||
// Lock for sBackgroundThread.
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
|
||||
if (!sBackgroundThread) {
|
||||
if (!sFactory) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Guaranteed to succeed because we should get abort only before the
|
||||
// background thread is destroyed.
|
||||
nsCOMPtr<nsIRunnable> runnable = new AbortRunnable(aOrigin);
|
||||
nsresult rv = sBackgroundThread->Dispatch(runnable,
|
||||
nsIThread::DISPATCH_NORMAL);
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(rv));
|
||||
MOZ_ASSERT(!sFactory->mManagerList.IsEmpty());
|
||||
|
||||
{
|
||||
ManagerList::ForwardIterator iter(sFactory->mManagerList);
|
||||
while (iter.HasMore()) {
|
||||
RefPtr<Manager> manager = iter.GetNext();
|
||||
if (aOrigin.IsVoid() ||
|
||||
manager->mManagerId->QuotaOrigin() == aOrigin) {
|
||||
manager->Abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
StartShutdownAllOnMainThread()
|
||||
ShutdownAll()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mozilla::ipc::AssertIsOnBackgroundThread();
|
||||
|
||||
// Lock for sFactoryShutdown and sBackgroundThread.
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
|
||||
sFactoryShutdown = true;
|
||||
|
||||
if (!sBackgroundThread) {
|
||||
if (!sFactory) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Guaranteed to succeed because we should be shutdown before the
|
||||
// background thread is destroyed.
|
||||
nsCOMPtr<nsIRunnable> runnable = new ShutdownAllRunnable();
|
||||
nsresult rv = sBackgroundThread->Dispatch(runnable,
|
||||
nsIThread::DISPATCH_NORMAL);
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(rv));
|
||||
MOZ_ASSERT(!sFactory->mManagerList.IsEmpty());
|
||||
|
||||
{
|
||||
// Note that we are synchronously calling shutdown code here. If any
|
||||
// of the shutdown code synchronously decides to delete the Factory
|
||||
// we need to delay that delete until the end of this method.
|
||||
AutoRestore<bool> restore(sFactory->mInSyncShutdown);
|
||||
sFactory->mInSyncShutdown = true;
|
||||
|
||||
ManagerList::ForwardIterator iter(sFactory->mManagerList);
|
||||
while (iter.HasMore()) {
|
||||
RefPtr<Manager> manager = iter.GetNext();
|
||||
manager->Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
MaybeDestroyInstance();
|
||||
}
|
||||
|
||||
static bool
|
||||
IsShutdownAllCompleteOnMainThread()
|
||||
IsShutdownAllComplete()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
// Infer whether we have shutdown using the sBackgroundThread value. We
|
||||
// guarantee this is nullptr when sFactory is destroyed.
|
||||
return sFactoryShutdown && !sBackgroundThread;
|
||||
mozilla::ipc::AssertIsOnBackgroundThread();
|
||||
return !sFactory;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -322,12 +328,6 @@ private:
|
|||
if (sFactoryShutdown) {
|
||||
return NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
|
||||
}
|
||||
|
||||
// Cannot use ClearOnShutdown() because we're on the background thread.
|
||||
// This is automatically cleared when Factory::Remove() calls
|
||||
// MaybeDestroyInstance().
|
||||
MOZ_ASSERT(!sBackgroundThread);
|
||||
sBackgroundThread = NS_GetCurrentThread();
|
||||
}
|
||||
|
||||
// We cannot use ClearOnShutdown() here because we're not on the main
|
||||
|
@ -359,134 +359,21 @@ private:
|
|||
return;
|
||||
}
|
||||
|
||||
// Be clear about what we are locking. sFactory is bg thread only, so
|
||||
// we don't need to lock it here. Just protect sBackgroundThread.
|
||||
{
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
MOZ_ASSERT(sBackgroundThread);
|
||||
sBackgroundThread = nullptr;
|
||||
}
|
||||
|
||||
sFactory = nullptr;
|
||||
}
|
||||
|
||||
static void
|
||||
AbortOnBackgroundThread(const nsACString& aOrigin)
|
||||
{
|
||||
mozilla::ipc::AssertIsOnBackgroundThread();
|
||||
|
||||
// The factory was destroyed between when abort started on main thread and
|
||||
// when we could start abort on the worker thread. Just declare abort
|
||||
// complete.
|
||||
if (!sFactory) {
|
||||
#ifdef DEBUG
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
MOZ_ASSERT(!sBackgroundThread);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!sFactory->mManagerList.IsEmpty());
|
||||
|
||||
{
|
||||
ManagerList::ForwardIterator iter(sFactory->mManagerList);
|
||||
while (iter.HasMore()) {
|
||||
RefPtr<Manager> manager = iter.GetNext();
|
||||
if (aOrigin.IsVoid() ||
|
||||
manager->mManagerId->QuotaOrigin() == aOrigin) {
|
||||
manager->Abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ShutdownAllOnBackgroundThread()
|
||||
{
|
||||
mozilla::ipc::AssertIsOnBackgroundThread();
|
||||
|
||||
// The factory shutdown between when shutdown started on main thread and
|
||||
// when we could start shutdown on the worker thread. Just declare
|
||||
// shutdown complete. The sFactoryShutdown flag prevents the factory
|
||||
// from racing to restart here.
|
||||
if (!sFactory) {
|
||||
#ifdef DEBUG
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
MOZ_ASSERT(!sBackgroundThread);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!sFactory->mManagerList.IsEmpty());
|
||||
|
||||
{
|
||||
// Note that we are synchronously calling shutdown code here. If any
|
||||
// of the shutdown code synchronously decides to delete the Factory
|
||||
// we need to delay that delete until the end of this method.
|
||||
AutoRestore<bool> restore(sFactory->mInSyncShutdown);
|
||||
sFactory->mInSyncShutdown = true;
|
||||
|
||||
ManagerList::ForwardIterator iter(sFactory->mManagerList);
|
||||
while (iter.HasMore()) {
|
||||
RefPtr<Manager> manager = iter.GetNext();
|
||||
manager->Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
MaybeDestroyInstance();
|
||||
}
|
||||
|
||||
class AbortRunnable final : public nsRunnable
|
||||
{
|
||||
public:
|
||||
explicit AbortRunnable(const nsACString& aOrigin)
|
||||
: mOrigin(aOrigin)
|
||||
{ }
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override
|
||||
{
|
||||
mozilla::ipc::AssertIsOnBackgroundThread();
|
||||
AbortOnBackgroundThread(mOrigin);
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
~AbortRunnable() { }
|
||||
|
||||
const nsCString mOrigin;
|
||||
};
|
||||
|
||||
class ShutdownAllRunnable final : public nsRunnable
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD
|
||||
Run() override
|
||||
{
|
||||
mozilla::ipc::AssertIsOnBackgroundThread();
|
||||
ShutdownAllOnBackgroundThread();
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
~ShutdownAllRunnable() { }
|
||||
};
|
||||
|
||||
// Singleton created on demand and deleted when last Manager is cleared
|
||||
// in Remove().
|
||||
// PBackground thread only.
|
||||
static StaticAutoPtr<Factory> sFactory;
|
||||
|
||||
// protects following static attributes
|
||||
// protects following static attribute
|
||||
static StaticMutex sMutex;
|
||||
|
||||
// Indicate if shutdown has occurred to block re-creation of sFactory.
|
||||
// Must hold sMutex to access.
|
||||
static bool sFactoryShutdown;
|
||||
|
||||
// Background thread owning all Manager objects. Only set while sFactory is
|
||||
// set.
|
||||
// Must hold sMutex to access.
|
||||
static StaticRefPtr<nsIThread> sBackgroundThread;
|
||||
|
||||
// Weak references as we don't want to keep Manager objects alive forever.
|
||||
// When a Manager is destroyed it calls Factory::Remove() to clear itself.
|
||||
// PBackground thread only.
|
||||
|
@ -508,9 +395,6 @@ StaticMutex Manager::Factory::sMutex;
|
|||
// static
|
||||
bool Manager::Factory::sFactoryShutdown = false;
|
||||
|
||||
// static
|
||||
StaticRefPtr<nsIThread> Manager::Factory::sBackgroundThread;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Abstract class to help implement the various Actions. The vast majority
|
||||
|
@ -1531,13 +1415,13 @@ Manager::Get(ManagerId* aManagerId)
|
|||
|
||||
// static
|
||||
void
|
||||
Manager::ShutdownAllOnMainThread()
|
||||
Manager::ShutdownAll()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mozilla::ipc::AssertIsOnBackgroundThread();
|
||||
|
||||
Factory::StartShutdownAllOnMainThread();
|
||||
Factory::ShutdownAll();
|
||||
|
||||
while (!Factory::IsShutdownAllCompleteOnMainThread()) {
|
||||
while (!Factory::IsShutdownAllComplete()) {
|
||||
if (!NS_ProcessNextEvent()) {
|
||||
NS_WARNING("Something bad happened!");
|
||||
break;
|
||||
|
@ -1547,11 +1431,11 @@ Manager::ShutdownAllOnMainThread()
|
|||
|
||||
// static
|
||||
void
|
||||
Manager::AbortOnMainThread(const nsACString& aOrigin)
|
||||
Manager::Abort(const nsACString& aOrigin)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mozilla::ipc::AssertIsOnBackgroundThread();
|
||||
|
||||
Factory::StartAbortOnMainThread(aOrigin);
|
||||
Factory::Abort(aOrigin);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -131,11 +131,11 @@ public:
|
|||
static nsresult GetOrCreate(ManagerId* aManagerId, Manager** aManagerOut);
|
||||
static already_AddRefed<Manager> Get(ManagerId* aManagerId);
|
||||
|
||||
// Synchronously shutdown from main thread. This spins the event loop.
|
||||
static void ShutdownAllOnMainThread();
|
||||
// Synchronously shutdown. This spins the event loop.
|
||||
static void ShutdownAll();
|
||||
|
||||
// Cancel actions for given origin or all actions if passed string is null.
|
||||
static void AbortOnMainThread(const nsACString& aOrigin);
|
||||
static void Abort(const nsACString& aOrigin);
|
||||
|
||||
// Must be called by Listener objects before they are destroyed.
|
||||
void RemoveListener(Listener* aListener);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "mozilla/dom/cache/Manager.h"
|
||||
#include "mozilla/dom/quota/QuotaManager.h"
|
||||
#include "mozilla/dom/quota/UsageInfo.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
@ -23,6 +24,7 @@ using mozilla::dom::quota::Client;
|
|||
using mozilla::dom::quota::PersistenceType;
|
||||
using mozilla::dom::quota::QuotaManager;
|
||||
using mozilla::dom::quota::UsageInfo;
|
||||
using mozilla::ipc::AssertIsOnBackgroundThread;
|
||||
|
||||
static nsresult
|
||||
GetBodyUsage(nsIFile* aDir, UsageInfo* aUsageInfo)
|
||||
|
@ -175,9 +177,9 @@ public:
|
|||
virtual void
|
||||
AbortOperations(const nsACString& aOrigin) override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
Manager::AbortOnMainThread(aOrigin);
|
||||
Manager::Abort(aOrigin);
|
||||
}
|
||||
|
||||
virtual void
|
||||
|
@ -195,22 +197,26 @@ public:
|
|||
}
|
||||
|
||||
virtual void
|
||||
PerformIdleMaintenance() override
|
||||
StartIdleMaintenance() override
|
||||
{ }
|
||||
|
||||
virtual void
|
||||
StopIdleMaintenance() override
|
||||
{ }
|
||||
|
||||
virtual void
|
||||
ShutdownWorkThreads() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
// spins the event loop and synchronously shuts down all Managers
|
||||
Manager::ShutdownAllOnMainThread();
|
||||
Manager::ShutdownAll();
|
||||
}
|
||||
|
||||
private:
|
||||
~CacheQuotaClient()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AssertIsOnBackgroundThread();
|
||||
}
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(CacheQuotaClient, override)
|
||||
|
@ -224,6 +230,8 @@ namespace cache {
|
|||
|
||||
already_AddRefed<quota::Client> CreateQuotaClient()
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
RefPtr<CacheQuotaClient> ref = new CacheQuotaClient();
|
||||
return ref.forget();
|
||||
}
|
||||
|
|
|
@ -35,7 +35,11 @@ function runTests(testFile, order) {
|
|||
// adapted from dom/indexedDB/test/helpers.js
|
||||
function clearStorage() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
SpecialPowers.clearStorageForDoc(SpecialPowers.wrap(document), resolve);
|
||||
var qms = SpecialPowers.Services.qms;
|
||||
var principal = SpecialPowers.wrap(document).nodePrincipal;
|
||||
var request = qms.clearStoragesForPrincipal(principal);
|
||||
var cb = SpecialPowers.wrapCallback(resolve);
|
||||
request.callback = cb;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -24,19 +24,31 @@ function setupTestIframe() {
|
|||
|
||||
function clearStorage() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
SpecialPowers.clearStorageForDoc(SpecialPowers.wrap(document), resolve);
|
||||
var qms = SpecialPowers.Services.qms;
|
||||
var principal = SpecialPowers.wrap(document).nodePrincipal;
|
||||
var request = qms.clearStoragesForPrincipal(principal);
|
||||
var cb = SpecialPowers.wrapCallback(resolve);
|
||||
request.callback = cb;
|
||||
});
|
||||
}
|
||||
|
||||
function storageUsage() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
SpecialPowers.getStorageUsageForDoc(SpecialPowers.wrap(document), resolve);
|
||||
var qms = SpecialPowers.Services.qms;
|
||||
var principal = SpecialPowers.wrap(document).nodePrincipal;
|
||||
var cb = SpecialPowers.wrapCallback(function(request) {
|
||||
resolve(request.usage, request.fileUsage);
|
||||
});
|
||||
qms.getUsageForPrincipal(principal, cb);
|
||||
});
|
||||
}
|
||||
|
||||
function resetStorage() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
SpecialPowers.resetStorageForDoc(SpecialPowers.wrap(document), resolve);
|
||||
var qms = SpecialPowers.Services.qms;
|
||||
var request = qms.reset();
|
||||
var cb = SpecialPowers.wrapCallback(resolve);
|
||||
request.callback = cb;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -24,19 +24,31 @@ function setupTestIframe() {
|
|||
|
||||
function clearStorage() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
SpecialPowers.clearStorageForDoc(SpecialPowers.wrap(document), resolve);
|
||||
var qms = SpecialPowers.Services.qms;
|
||||
var principal = SpecialPowers.wrap(document).nodePrincipal;
|
||||
var request = qms.clearStoragesForPrincipal(principal);
|
||||
var cb = SpecialPowers.wrapCallback(resolve);
|
||||
request.callback = cb;
|
||||
});
|
||||
}
|
||||
|
||||
function storageUsage() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
SpecialPowers.getStorageUsageForDoc(SpecialPowers.wrap(document), resolve);
|
||||
var qms = SpecialPowers.Services.qms;
|
||||
var principal = SpecialPowers.wrap(document).nodePrincipal;
|
||||
var cb = SpecialPowers.wrapCallback(function(request) {
|
||||
resolve(request.usage, request.fileUsage);
|
||||
});
|
||||
qms.getUsageForPrincipal(principal, cb);
|
||||
});
|
||||
}
|
||||
|
||||
function resetStorage() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
SpecialPowers.resetStorageForDoc(SpecialPowers.wrap(document), resolve);
|
||||
var qms = SpecialPowers.Services.qms;
|
||||
var request = qms.reset();
|
||||
var cb = SpecialPowers.wrapCallback(resolve);
|
||||
request.callback = cb;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,10 @@ function setupTestIframe() {
|
|||
|
||||
function resetStorage() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
SpecialPowers.resetStorageForDoc(SpecialPowers.wrap(document), resolve);
|
||||
var qms = SpecialPowers.Services.qms;
|
||||
var request = qms.reset();
|
||||
var cb = SpecialPowers.wrapCallback(resolve);
|
||||
request.callback = cb;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -24,19 +24,31 @@ function setupTestIframe() {
|
|||
|
||||
function clearStorage() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
SpecialPowers.clearStorageForDoc(SpecialPowers.wrap(document), resolve);
|
||||
var qms = SpecialPowers.Services.qms;
|
||||
var principal = SpecialPowers.wrap(document).nodePrincipal;
|
||||
var request = qms.clearStoragesForPrincipal(principal);
|
||||
var cb = SpecialPowers.wrapCallback(resolve);
|
||||
request.callback = cb;
|
||||
});
|
||||
}
|
||||
|
||||
function storageUsage() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
SpecialPowers.getStorageUsageForDoc(SpecialPowers.wrap(document), resolve);
|
||||
var qms = SpecialPowers.Services.qms;
|
||||
var principal = SpecialPowers.wrap(document).nodePrincipal;
|
||||
var cb = SpecialPowers.wrapCallback(function(request) {
|
||||
resolve(request.usage, request.fileUsage);
|
||||
});
|
||||
qms.getUsageForPrincipal(principal, cb);
|
||||
});
|
||||
}
|
||||
|
||||
function resetStorage() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
SpecialPowers.resetStorageForDoc(SpecialPowers.wrap(document), resolve);
|
||||
var qms = SpecialPowers.Services.qms;
|
||||
var request = qms.reset();
|
||||
var cb = SpecialPowers.wrapCallback(resolve);
|
||||
request.callback = cb;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -92,22 +92,11 @@ function resetQuotaManager() {
|
|||
var pref = 'dom.quotaManager.testing';
|
||||
prefService.getBranch(null).setBoolPref(pref, true);
|
||||
|
||||
qm.reset();
|
||||
var request = qm.reset();
|
||||
request.callback = resolve;
|
||||
|
||||
// disable quota manager testing mode
|
||||
//prefService.getBranch(null).setBoolPref(pref, false);
|
||||
|
||||
var uri = Cc['@mozilla.org/network/io-service;1']
|
||||
.getService(Ci.nsIIOService)
|
||||
.newURI('http://example.com', null, null);
|
||||
var principal = Cc['@mozilla.org/scriptsecuritymanager;1']
|
||||
.getService(Ci.nsIScriptSecurityManager)
|
||||
.getSystemPrincipal();
|
||||
|
||||
// use getUsageForPrincipal() to get a callback when the reset() is done
|
||||
qm.getUsageForPrincipal(principal, function(principal, usage, fileUsage) {
|
||||
resolve(usage);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче