/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=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/. */
class LocalStorageCacheBridge; class StorageUsageBridge; class StorageUsage;
using StatementCache = mozilla::storage::StatementCache<mozIStorageStatement>;
// XXX Fix me! // 1. Move comments to StorageDBThread/StorageDBChild. // 2. Devirtualize relevant methods in StorageDBThread/StorageDBChild. // 3. Remove relevant methods in StorageDBThread/StorageDBChild that are // unused. // 4. Remove this class completely. // // See bug 1387636 for more details. #if 0 // Interface used by the cache to post operations to the asynchronous // database thread or process. class StorageDBBridge
{ public:
StorageDBBridge(); virtual ~StorageDBBridge() {}
// Ensures the database engine is started virtual nsresult Init() = 0;
// Releases the database and disallows its usage virtual nsresult Shutdown() = 0;
// Asynchronously fills the cache with data from the database for first use. // When |aPriority| is true, the preload operation is scheduled as the first // one. This method is responsible to keep hard reference to the cache for // the time of the preload or, when preload cannot be performed, call // LoadDone() immediately. virtualvoid AsyncPreload(LocalStorageCacheBridge* aCache, bool aPriority = false) = 0;
// Asynchronously fill the |usage| object with actual usage of data by its // scope. The scope is eTLD+1 tops, never deeper subdomains. virtualvoid AsyncGetUsage(StorageUsageBridge* aUsage) = 0;
// Synchronously fills the cache, when |aForceSync| is false and cache already // got some data before, the method waits for the running preload to finish virtualvoid SyncPreload(LocalStorageCacheBridge* aCache, bool aForceSync = false) = 0;
// Called when an existing key is modified in the storage, schedules update to // the database virtual nsresult AsyncAddItem(LocalStorageCacheBridge* aCache, const nsAString& aKey, const nsAString& aValue) = 0;
// Called when an existing key is modified in the storage, schedules update to // the database virtual nsresult AsyncUpdateItem(LocalStorageCacheBridge* aCache, const nsAString& aKey, const nsAString& aValue) = 0;
// Called when an item is removed from the storage, schedules delete of the // key virtual nsresult AsyncRemoveItem(LocalStorageCacheBridge* aCache, const nsAString& aKey) = 0;
// Called when the whole storage is cleared by the DOM API, schedules delete // of the scope virtual nsresult AsyncClear(LocalStorageCacheBridge* aCache) = 0;
// Called when chrome deletes e.g. cookies, schedules delete of the whole // database virtualvoid AsyncClearAll() = 0;
// Called when only a domain and its subdomains is about to clear virtualvoid AsyncClearMatchingOrigin(const nsACString& aOriginNoSuffix) = 0;
// Called when data matching an origin pattern have to be cleared virtualvoid AsyncClearMatchingOriginAttributes(const OriginAttributesPattern& aPattern) = 0;
// Forces scheduled DB operations to be early flushed to the disk virtualvoid AsyncFlush() = 0;
// Check whether the scope has any data stored on disk and is thus allowed to // preload virtualbool ShouldPreloadOrigin(const nsACString& aOriginNoSuffix) = 0;
}; #endif
// The implementation of the the database engine, this directly works // with the sqlite or any other db API we are based on // This class is resposible for collecting and processing asynchronous // DB operations over caches (LocalStorageCache) communicating though // LocalStorageCacheBridge interface class class StorageDBThread final { public: class PendingOperations;
// Representation of a singe database task, like adding and removing keys, // (pre)loading the whole origin data, cleaning. class DBOperation { public: enum OperationType { // Only operation that reads data from the database
opPreload, // The same as opPreload, just executed with highest priority
opPreloadUrgent,
// Load usage of a scope
opGetUsage,
// Operations invoked by the DOM content API
opAddItem,
opUpdateItem,
opRemoveItem, // Clears a specific single origin data
opClear,
// Operations invoked by chrome
// Clear all the data stored in the database, for all scopes, no // exceptions
opClearAll, // Clear data under a domain and all its subdomains regardless // OriginAttributes value
opClearMatchingOrigin, // Clear all data matching an OriginAttributesPattern regardless a domain
opClearMatchingOriginAttributes,
};
// Executes the operation, doesn't necessarity have to be called on the I/O // thread void PerformAndFinalize(StorageDBThread* aThread);
// Finalize the operation, i.e. do any internal cleanup and finish calls void Finalize(nsresult aRv);
// The operation type
OperationType Type() const { return mType; }
// The origin in the database usage format (reversed) const nsCString OriginNoSuffix() const;
// The origin attributes suffix const nsCString OriginSuffix() const;
// |origin suffix + origin key| the operation is working with or a scope // pattern to delete with simple SQL's "LIKE %" from the database. const nsCString Origin() const;
// |origin suffix + origin key + key| the operation is working with const nsCString Target() const;
// Pattern to delete matching data with this op const OriginAttributesPattern& OriginPattern() const { return mOriginPattern;
}
private: // The operation implementation body
nsresult Perform(StorageDBThread* aThread);
// Encapsulation of collective and coalescing logic for all pending operations // except preloads that are handled separately as priority operations class PendingOperations { public:
PendingOperations();
// Method responsible for coalescing redundant update operations with the // same |Target()| or clear operations with the same or matching |Origin()| void Add(UniquePtr<DBOperation> aOperation);
// True when there are some scheduled operations to flush on disk bool HasTasks() const;
// Moves collected operations to a local flat list to allow execution of the // operation list out of the thread lock bool Prepare();
// Executes the previously |Prepared()'ed| list of operations, returns // result, but doesn't handle it in any way in case of a failure
nsresult Execute(StorageDBThread* aThread);
// Finalizes the pending operation list, returns false when too many // operations failed to flush what indicates a long standing issue with the // database access. bool Finalize(nsresult aRv);
// true when a clear that deletes the given origin attr pattern and/or // origin key is among the pending operations; when a preload for that scope // is being scheduled, it must be finished right away bool IsOriginClearPending(const nsACString& aOriginSuffix, const nsACString& aOriginNoSuffix) const;
// Checks whether there is a pending update operation for this scope. bool IsOriginUpdatePending(const nsACString& aOriginSuffix, const nsACString& aOriginNoSuffix) const;
private: // Returns true iff new operation is of type newType and there is a pending // operation of type pendingType for the same key (target). bool CheckForCoalesceOpportunity(DBOperation* aNewOp,
DBOperation::OperationType aPendingType,
DBOperation::OperationType aNewType);
// List of all clearing operations, executed first
nsClassHashtable<nsCStringHashKey, DBOperation> mClears;
// List of all update/insert operations, executed as second
nsClassHashtable<nsCStringHashKey, DBOperation> mUpdates;
// Collection of all tasks, valid only between Prepare() and Execute()
nsTArray<UniquePtr<DBOperation> > mExecList;
// Number of failing flush attempts
uint32_t mFlushFailureCount;
};
class ThreadObserver final : public nsIThreadObserver {
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSITHREADOBSERVER
private: virtual ~ThreadObserver() = default; bool mHasPendingEvents; // The monitor we drive the thread with
Monitor mMonitor MOZ_UNANNOTATED;
};
class InitHelper;
class NoteBackgroundThreadRunnable;
class ShutdownRunnable : public Runnable { // Expected to be only 0 or 1. const uint32_t mPrivateBrowsingId; // Only touched on the main thread. bool& mDone;
// Used to observe runnables dispatched to our thread and to monitor it.
RefPtr<ThreadObserver> mThreadObserver;
// Flag to stop, protected by the monitor returned by // mThreadObserver->GetMonitor(). bool mStopIOThread;
// Whether WAL is enabled bool mWALModeEnabled;
// Whether DB has already been open, avoid races between main thread reads // and pending DB init in the background I/O thread
Atomic<bool, ReleaseAcquire> mDBReady;
// State of the database initiation
nsresult mStatus;
// List of origins (including origin attributes suffix) having data, for // optimization purposes only
nsTHashSet<nsCString> mOriginsHavingData;
// Connection used by the worker thread for all read and write ops
nsCOMPtr<mozIStorageConnection> mWorkerConnection;
// Connection used only on the main thread for sync read operations
nsCOMPtr<mozIStorageConnection> mReaderConnection;
// Time the first pending operation has been added to the pending operations // list
TimeStamp mDirtyEpoch;
// Flag to force immediate flush of all pending operations bool mFlushImmediately;
// List of preloading operations, in chronological or priority order. // Executed prioritly over pending update operations.
nsTArray<DBOperation*> mPreloads;
// Collector of pending update operations
PendingOperations mPendingTasks;
// Expected to be only 0 or 1. const uint32_t mPrivateBrowsingId;
// Counter of calls for thread priority rising.
int32_t mPriorityCounter;
// Helper to direct an operation to one of the arrays above; // also checks IsOriginClearPending for preloads
nsresult InsertDBOp(UniquePtr<DBOperation> aOperation);
// Opens the database, first thing we do after start of the thread.
nsresult OpenDatabaseConnection();
nsresult OpenAndUpdateDatabase();
nsresult InitDatabase();
nsresult ShutdownDatabase();
// Ensures we flush pending tasks in some reasonble time void ScheduleFlush();
// Called when flush of pending tasks is being executed void UnscheduleFlush();
// This method is used for two purposes: // 1. as a value passed to monitor.Wait() method // 2. as in indicator that flush has to be performed // // Return: // - TimeDuration::Forever() when no pending tasks are scheduled // - Non-zero TimeDuration when tasks have been scheduled, but it // is still not time to perform the flush ; it is actual time to // wait until the flush has to happen. // - 0 TimeDuration when it is time to do the flush
TimeDuration TimeUntilFlush();
// Notifies to the main thread that flush has completed void NotifyFlushCompletion();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.