Bug 1131766 - Use a simpler thread model for IndexedDB transactions, r=khuey.

This commit is contained in:
Ben Turner 2014-12-02 12:01:44 -08:00
parent 7956cb8b3d
commit 39370e837c
8 changed files with 4023 additions and 2544 deletions

File diff suppressed because it is too large Load Diff

View File

@ -278,7 +278,7 @@ LoggingHelper(bool aUseProfiler, const char* aFmt, ...)
PRLogModuleInfo* logModule = IndexedDatabaseManager::GetLoggingModule();
MOZ_ASSERT(logModule);
static const PRLogModuleLevel logLevel = PR_LOG_DEBUG;
static const PRLogModuleLevel logLevel = PR_LOG_WARNING;
if (PR_LOG_TEST(logModule, logLevel) ||
(aUseProfiler && profiler_is_active())) {

File diff suppressed because it is too large Load Diff

View File

@ -1,159 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_indexeddb_transactionthreadpool_h__
#define mozilla_dom_indexeddb_transactionthreadpool_h__
#include "mozilla/Attributes.h"
#include "nsAutoPtr.h"
#include "nsClassHashtable.h"
#include "nsCOMPtr.h"
#include "nsHashKeys.h"
#include "nsISupportsImpl.h"
#include "nsTArray.h"
struct nsID;
class nsIEventTarget;
class nsIRunnable;
class nsIThreadPool;
namespace mozilla {
namespace dom {
namespace indexedDB {
class TransactionThreadPool final
{
class FinishTransactionRunnable;
friend class FinishTransactionRunnable;
class TransactionQueue;
friend class TransactionQueue;
struct DatabaseTransactionInfo;
struct DatabasesCompleteCallback;
struct TransactionInfo;
struct TransactionInfoPair;
nsCOMPtr<nsIThreadPool> mThreadPool;
nsCOMPtr<nsIEventTarget> mOwningThread;
nsClassHashtable<nsCStringHashKey, DatabaseTransactionInfo>
mTransactionsInProgress;
nsTArray<nsAutoPtr<DatabasesCompleteCallback>> mCompleteCallbacks;
uint64_t mNextTransactionId;
bool mShutdownRequested;
bool mShutdownComplete;
public:
class FinishCallback;
static already_AddRefed<TransactionThreadPool> Create();
uint64_t NextTransactionId();
void Start(uint64_t aTransactionId,
const nsACString& aDatabaseId,
const nsTArray<nsString>& aObjectStoreNames,
uint16_t aMode,
const nsID& aBackgroundChildLoggingId,
int64_t aLoggingSerialNumber,
nsIRunnable* aRunnable);
void Dispatch(uint64_t aTransactionId,
const nsACString& aDatabaseId,
nsIRunnable* aRunnable,
bool aFinish,
FinishCallback* aFinishCallback);
void WaitForDatabasesToComplete(nsTArray<nsCString>& aDatabaseIds,
nsIRunnable* aCallback);
NS_INLINE_DECL_REFCOUNTING(TransactionThreadPool)
void Shutdown();
void AssertIsOnOwningThread() const
#ifdef DEBUG
;
#else
{ }
#endif
private:
static PLDHashOperator
CollectTransactions(const uint64_t& aTransactionId,
TransactionInfo* aValue,
void* aUserArg);
static PLDHashOperator
FindTransaction(const uint64_t& aTransactionId,
TransactionInfo* aValue,
void* aUserArg);
static PLDHashOperator
MaybeUnblockTransaction(nsPtrHashKey<TransactionInfo>* aKey,
void* aUserArg);
TransactionThreadPool();
// Reference counted.
~TransactionThreadPool();
nsresult Init();
void Cleanup();
void FinishTransaction(uint64_t aTransactionId,
const nsACString& aDatabaseId,
const nsTArray<nsString>& aObjectStoreNames,
uint16_t aMode);
TransactionQueue* GetQueueForTransaction(uint64_t aTransactionId,
const nsACString& aDatabaseId);
TransactionQueue& CreateQueueForTransaction(
uint64_t aTransactionId,
const nsACString& aDatabaseId,
const nsTArray<nsString>& aObjectStoreNames,
uint16_t aMode,
const nsID& aBackgroundChildLoggingId,
int64_t aLoggingSerialNumber);
bool MaybeFireCallback(DatabasesCompleteCallback* aCallback);
void CleanupAsync();
};
class NS_NO_VTABLE TransactionThreadPool::FinishCallback
{
public:
NS_IMETHOD_(MozExternalRefCountType)
AddRef() = 0;
NS_IMETHOD_(MozExternalRefCountType)
Release() = 0;
// Called on the owning thread before any additional transactions are
// unblocked.
virtual void
TransactionFinishedBeforeUnblock() = 0;
// Called on the owning thread after additional transactions may have been
// unblocked.
virtual void
TransactionFinishedAfterUnblock() = 0;
protected:
FinishCallback()
{ }
};
} // namespace indexedDB
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_indexeddb_transactionthreadpool_h__

View File

@ -64,7 +64,6 @@ UNIFIED_SOURCES += [
'KeyPath.cpp',
'PermissionRequestBase.cpp',
'ReportInternalError.cpp',
'TransactionThreadPool.cpp',
]
SOURCES += [

View File

@ -3,6 +3,14 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var disableWorkerTest =
"This test requires a precise 'executeSoon()' to complete reliably. On a " +
"worker 'executeSoon()' currently uses 'setTimeout()', and that switches " +
"to the timer thread and back before completing. That gives the IndexedDB " +
"transaction thread time to fully complete transactions and to place " +
"'complete' events in the worker thread's queue before the timer event, " +
"causing ordering problems in the spot marked 'Worker Fails Here' below.";
var testGenerator = testSteps();
var abortFired = false;
@ -330,6 +338,8 @@ function testSteps()
// During COMMITTING
transaction = db.transaction("foo", "readwrite");
transaction.objectStore("foo").put({hello: "world"}, 1).onsuccess = function(event) {
// Worker Fails Here! Due to the thread switching of 'executeSoon()' the
// transaction can commit and fire a 'complete' event before we continue.
continueToNextStep();
};
yield undefined;

View File

@ -353,20 +353,6 @@ OriginInfo::LockedDecreaseUsage(int64_t aSize)
quotaManager->mTemporaryStorageUsage -= aSize;
}
// static
PLDHashOperator
OriginInfo::ClearOriginInfoCallback(const nsAString& aKey,
QuotaObject* aValue,
void* aUserArg)
{
NS_ASSERTION(!aKey.IsEmpty(), "Empty key!");
NS_ASSERTION(aValue, "Null pointer!");
aValue->mOriginInfo = nullptr;
return PL_DHASH_NEXT;
}
already_AddRefed<OriginInfo>
GroupInfo::LockedGetOriginInfo(const nsACString& aOrigin)
{

View File

@ -96,6 +96,8 @@ private:
~OriginInfo()
{
MOZ_COUNT_DTOR(OriginInfo);
MOZ_ASSERT(!mQuotaObjects.Count());
}
void
@ -109,18 +111,6 @@ private:
mAccessTime = aAccessTime;
}
void
LockedClearOriginInfos()
{
AssertCurrentThreadOwnsQuotaMutex();
mQuotaObjects.EnumerateRead(ClearOriginInfoCallback, nullptr);
}
static PLDHashOperator
ClearOriginInfoCallback(const nsAString& aKey,
QuotaObject* aValue, void* aUserArg);
nsDataHashtable<nsStringHashKey, QuotaObject*> mQuotaObjects;
GroupInfo* mGroupInfo;