зеркало из https://github.com/mozilla/pjs.git
Bug 624047 - LocalStorage value is lost after a few seconds, r=jst, a=final+
This commit is contained in:
Родитель
2fd1892a9d
Коммит
cacc4845fc
|
@ -281,6 +281,12 @@ nsDOMStorageManager::Initialize()
|
|||
os->AddObserver(gStorageManager, "profile-after-change", PR_FALSE);
|
||||
os->AddObserver(gStorageManager, "perm-changed", PR_FALSE);
|
||||
os->AddObserver(gStorageManager, "browser:purge-domain-data", PR_FALSE);
|
||||
#ifdef MOZ_STORAGE
|
||||
// Used for temporary table flushing
|
||||
os->AddObserver(gStorageManager, "profile-before-change", PR_FALSE);
|
||||
os->AddObserver(gStorageManager, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE);
|
||||
os->AddObserver(gStorageManager, NS_DOMSTORAGE_FLUSH_TIMER_OBSERVER, PR_FALSE);
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -441,8 +447,6 @@ nsDOMStorageManager::Observe(nsISupports *aSubject,
|
|||
nsCOMPtr<nsIObserverService> obsserv = mozilla::services::GetObserverService();
|
||||
if (obsserv)
|
||||
obsserv->NotifyObservers(nsnull, NS_DOMSTORAGE_FLUSH_TIMER_OBSERVER, nsnull);
|
||||
if (!UnflushedDataExists())
|
||||
DOMStorageImpl::gStorageDB->StopTempTableFlushTimer();
|
||||
} else if (!strcmp(aTopic, "browser:purge-domain-data")) {
|
||||
// Convert the domain name to the ACE format
|
||||
nsCAutoString aceDomain;
|
||||
|
@ -470,6 +474,19 @@ nsDOMStorageManager::Observe(nsISupports *aSubject,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
DOMStorageImpl::gStorageDB->RemoveOwner(aceDomain, PR_TRUE);
|
||||
} else if (!strcmp(aTopic, "profile-before-change") ||
|
||||
!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
|
||||
if (DOMStorageImpl::gStorageDB) {
|
||||
nsresult rv = DOMStorageImpl::gStorageDB->FlushAndDeleteTemporaryTables(true);
|
||||
if (NS_FAILED(rv))
|
||||
NS_WARNING("DOMStorage: temporary table commit failed");
|
||||
}
|
||||
} else if (!strcmp(aTopic, NS_DOMSTORAGE_FLUSH_TIMER_OBSERVER)) {
|
||||
if (DOMStorageImpl::gStorageDB) {
|
||||
nsresult rv = DOMStorageImpl::gStorageDB->FlushAndDeleteTemporaryTables(false);
|
||||
if (NS_FAILED(rv))
|
||||
NS_WARNING("DOMStorage: temporary table commit failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -539,26 +556,6 @@ nsDOMStorageManager::RemoveFromStoragesHash(DOMStorageImpl* aStorage)
|
|||
mStorages.RemoveEntry(aStorage);
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
CheckUnflushedData(nsDOMStorageEntry* aEntry, void* userArg)
|
||||
{
|
||||
if (aEntry->mStorage->WasTemporaryTableLoaded()) {
|
||||
PRBool *unflushedData = (PRBool*)userArg;
|
||||
*unflushedData = PR_TRUE;
|
||||
return PL_DHASH_STOP;
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsDOMStorageManager::UnflushedDataExists()
|
||||
{
|
||||
PRBool unflushedData = PR_FALSE;
|
||||
mStorages.EnumerateEntries(CheckUnflushedData, &unflushedData);
|
||||
return unflushedData;
|
||||
}
|
||||
|
||||
//
|
||||
// nsDOMStorage
|
||||
//
|
||||
|
@ -726,25 +723,19 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMStorageImpl)
|
|||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(DOMStorageImpl, nsIObserver)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(DOMStorageImpl, nsIObserver)
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMStorageImpl)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMStorageImpl)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMStorageImpl)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
DOMStorageImpl::DOMStorageImpl(nsDOMStorage* aStorage)
|
||||
: mLoadedTemporaryTable(false)
|
||||
{
|
||||
Init(aStorage);
|
||||
}
|
||||
|
||||
DOMStorageImpl::DOMStorageImpl(nsDOMStorage* aStorage, DOMStorageImpl& aThat)
|
||||
: DOMStorageBase(aThat)
|
||||
, mLoadedTemporaryTable(aThat.mLoadedTemporaryTable)
|
||||
, mLastTemporaryTableAccessTime(aThat.mLastTemporaryTableAccessTime)
|
||||
, mTemporaryTableAge(aThat.mTemporaryTableAge)
|
||||
{
|
||||
Init(aStorage);
|
||||
}
|
||||
|
@ -807,8 +798,6 @@ DOMStorageImpl::InitFromChild(bool aUseDB, bool aCanUseChromePersist,
|
|||
mQuotaDomainDBKey = aQuotaDomainDBKey;
|
||||
mQuotaETLDplus1DomainDBKey = aQuotaETLDplus1DomainDBKey;
|
||||
mStorageType = static_cast<nsPIDOMStorage::nsDOMStorageType>(aStorageType);
|
||||
if (mStorageType != nsPIDOMStorage::SessionStorage)
|
||||
RegisterObservers();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -828,14 +817,12 @@ DOMStorageImpl::InitAsLocalStorage(nsIURI* aDomainURI,
|
|||
bool aCanUseChromePersist)
|
||||
{
|
||||
DOMStorageBase::InitAsLocalStorage(aDomainURI, aCanUseChromePersist);
|
||||
RegisterObservers();
|
||||
}
|
||||
|
||||
void
|
||||
DOMStorageImpl::InitAsGlobalStorage(const nsACString& aDomainDemanded)
|
||||
{
|
||||
DOMStorageBase::InitAsGlobalStorage(aDomainDemanded);
|
||||
RegisterObservers();
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1032,86 +1019,6 @@ DOMStorageImpl::CloneFrom(bool aCallerSecure, DOMStorageBase* aThat)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
DOMStorageImpl::RegisterObservers()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obsserv = mozilla::services::GetObserverService();
|
||||
if (obsserv) {
|
||||
obsserv->AddObserver(this, "profile-before-change", PR_TRUE);
|
||||
obsserv->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_TRUE);
|
||||
obsserv->AddObserver(this, NS_DOMSTORAGE_FLUSH_TIMER_OBSERVER, PR_TRUE);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
DOMStorageImpl::MaybeCommitTemporaryTable(bool force)
|
||||
{
|
||||
#ifdef MOZ_STORAGE
|
||||
if (!UseDB())
|
||||
return NS_OK;
|
||||
|
||||
if (!mLoadedTemporaryTable)
|
||||
return NS_OK;
|
||||
|
||||
// If we are not forced to flush (e.g. on shutdown) then don't flush if the
|
||||
// last table access is less then 5 seconds ago or the table itself is not
|
||||
// older then 30 secs
|
||||
if (!force &&
|
||||
((TimeStamp::Now() - mLastTemporaryTableAccessTime).ToSeconds() <
|
||||
NS_DOMSTORAGE_MAXIMUM_TEMPTABLE_INACTIVITY_TIME) &&
|
||||
((TimeStamp::Now() - mTemporaryTableAge).ToSeconds() <
|
||||
NS_DOMSTORAGE_MAXIMUM_TEMPTABLE_AGE))
|
||||
return NS_OK;
|
||||
|
||||
return gStorageDB->FlushAndDeleteTemporaryTableForStorage(this);
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
DOMStorageImpl::WasTemporaryTableLoaded()
|
||||
{
|
||||
return mLoadedTemporaryTable;
|
||||
}
|
||||
|
||||
void
|
||||
DOMStorageImpl::SetTemporaryTableLoaded(bool loaded)
|
||||
{
|
||||
if (loaded) {
|
||||
mLastTemporaryTableAccessTime = TimeStamp::Now();
|
||||
if (!mLoadedTemporaryTable)
|
||||
mTemporaryTableAge = mLastTemporaryTableAccessTime;
|
||||
|
||||
gStorageDB->EnsureTempTableFlushTimer();
|
||||
}
|
||||
|
||||
mLoadedTemporaryTable = loaded;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
DOMStorageImpl::Observe(nsISupports *subject,
|
||||
const char *topic,
|
||||
const PRUnichar *data)
|
||||
{
|
||||
bool isProfileBeforeChange = !strcmp(topic, "profile-before-change");
|
||||
bool isXPCOMShutdown = !strcmp(topic, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
|
||||
bool isFlushTimer = !strcmp(topic, NS_DOMSTORAGE_FLUSH_TIMER_OBSERVER);
|
||||
|
||||
if (isXPCOMShutdown || isProfileBeforeChange || isFlushTimer) {
|
||||
nsresult rv = MaybeCommitTemporaryTable(isXPCOMShutdown || isProfileBeforeChange);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("DOMStorage: temporary table commit failed");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_WARNING("Unrecognized topic in nsDOMStorage::Observe");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
DOMStorageImpl::CacheKeysFromDB()
|
||||
{
|
||||
|
|
|
@ -61,7 +61,6 @@
|
|||
#include "nsIObserver.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
||||
#define NS_DOMSTORAGE_FLUSH_TIMER_OBSERVER "domstorage-flush-timer"
|
||||
|
||||
|
@ -76,9 +75,7 @@
|
|||
class nsDOMStorage;
|
||||
class nsIDOMStorage;
|
||||
class nsDOMStorageItem;
|
||||
|
||||
using mozilla::TimeStamp;
|
||||
using mozilla::TimeDuration;
|
||||
class nsDOMStoragePersistentDB;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -244,14 +241,11 @@ protected:
|
|||
};
|
||||
|
||||
class DOMStorageImpl : public DOMStorageBase
|
||||
, public nsIObserver
|
||||
, public nsSupportsWeakReference
|
||||
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(DOMStorageImpl, nsIObserver)
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(DOMStorageImpl)
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
DOMStorageImpl(nsDOMStorage*);
|
||||
DOMStorageImpl(nsDOMStorage*, DOMStorageImpl&);
|
||||
|
@ -314,12 +308,6 @@ public:
|
|||
virtual nsresult
|
||||
CloneFrom(bool aCallerSecure, DOMStorageBase* aThat);
|
||||
|
||||
nsresult RegisterObservers();
|
||||
nsresult MaybeCommitTemporaryTable(bool force);
|
||||
|
||||
bool WasTemporaryTableLoaded();
|
||||
void SetTemporaryTableLoaded(bool loaded);
|
||||
|
||||
virtual bool CacheStoragePermissions();
|
||||
|
||||
private:
|
||||
|
@ -327,6 +315,7 @@ private:
|
|||
static nsDOMStorageDBWrapper* gStorageDB;
|
||||
#endif
|
||||
friend class nsDOMStorageManager;
|
||||
friend class nsDOMStoragePersistentDB;
|
||||
friend class StorageParent;
|
||||
|
||||
void Init(nsDOMStorage*);
|
||||
|
@ -351,10 +340,6 @@ private:
|
|||
|
||||
// Weak reference to the owning storage instance
|
||||
nsDOMStorage* mOwner;
|
||||
|
||||
bool mLoadedTemporaryTable;
|
||||
TimeStamp mLastTemporaryTableAccessTime;
|
||||
TimeStamp mTemporaryTableAge;
|
||||
};
|
||||
|
||||
class nsDOMStorage : public nsIDOMStorageObsolete,
|
||||
|
|
|
@ -75,7 +75,6 @@ nsDOMStorageDBWrapper::nsDOMStorageDBWrapper()
|
|||
|
||||
nsDOMStorageDBWrapper::~nsDOMStorageDBWrapper()
|
||||
{
|
||||
StopTempTableFlushTimer();
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -99,29 +98,18 @@ nsDOMStorageDBWrapper::Init()
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsDOMStorageDBWrapper::EnsureLoadTemporaryTableForStorage(DOMStorageImpl* aStorage)
|
||||
nsDOMStorageDBWrapper::FlushAndDeleteTemporaryTables(bool force)
|
||||
{
|
||||
if (aStorage->CanUseChromePersist())
|
||||
return mChromePersistentDB.EnsureLoadTemporaryTableForStorage(aStorage);
|
||||
if (nsDOMStorageManager::gStorageManager->InPrivateBrowsingMode())
|
||||
return NS_OK;
|
||||
if (aStorage->SessionOnly())
|
||||
return NS_OK;
|
||||
nsresult rv1, rv2;
|
||||
rv1 = mChromePersistentDB.FlushTemporaryTables(force);
|
||||
rv2 = mPersistentDB.FlushTemporaryTables(force);
|
||||
|
||||
return mPersistentDB.EnsureLoadTemporaryTableForStorage(aStorage);
|
||||
}
|
||||
// Everything flushed? Then no need for a timer.
|
||||
if (!mChromePersistentDB.mTempTableLoads.Count() &&
|
||||
!mPersistentDB.mTempTableLoads.Count())
|
||||
StopTempTableFlushTimer();
|
||||
|
||||
nsresult
|
||||
nsDOMStorageDBWrapper::FlushAndDeleteTemporaryTableForStorage(DOMStorageImpl* aStorage)
|
||||
{
|
||||
if (aStorage->CanUseChromePersist())
|
||||
return mChromePersistentDB.FlushAndDeleteTemporaryTableForStorage(aStorage);
|
||||
if (nsDOMStorageManager::gStorageManager->InPrivateBrowsingMode())
|
||||
return NS_OK;
|
||||
if (aStorage->SessionOnly())
|
||||
return NS_OK;
|
||||
|
||||
return mPersistentDB.FlushAndDeleteTemporaryTableForStorage(aStorage);
|
||||
return NS_FAILED(rv1) ? rv1 : rv2;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -92,11 +92,6 @@ public:
|
|||
nsresult
|
||||
Init();
|
||||
|
||||
nsresult
|
||||
EnsureLoadTemporaryTableForStorage(DOMStorageImpl* aStorage);
|
||||
nsresult
|
||||
FlushAndDeleteTemporaryTableForStorage(DOMStorageImpl* aStorage);
|
||||
|
||||
/**
|
||||
* Retrieve a list of all the keys associated with a particular domain.
|
||||
*/
|
||||
|
@ -227,6 +222,14 @@ public:
|
|||
*/
|
||||
void EnsureTempTableFlushTimer();
|
||||
|
||||
/**
|
||||
* Called by the timer or on shutdown/profile change to flush all temporary
|
||||
* tables that are too long in memory to disk.
|
||||
* Set force to flush even a table doesn't meet the age limits. Used during
|
||||
* shutdown.
|
||||
*/
|
||||
nsresult FlushAndDeleteTemporaryTables(bool force);
|
||||
|
||||
/**
|
||||
* Stops the temp table flush timer.
|
||||
*/
|
||||
|
|
|
@ -55,6 +55,10 @@
|
|||
#include "nsPrintfCString.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
// Temporary tables for a storage scope will be flushed if found older
|
||||
// then this time in seconds since the load
|
||||
#define TEMP_TABLE_MAX_AGE (10) // seconds
|
||||
|
||||
class nsReverseStringSQLFunction : public mozIStorageFunction
|
||||
{
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -98,6 +102,7 @@ NS_IMPL_ISUPPORTS1(nsIsOfflineSQLFunction, mozIStorageFunction)
|
|||
|
||||
nsDOMStoragePersistentDB::nsDOMStoragePersistentDB()
|
||||
{
|
||||
mTempTableLoads.Init(16);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -446,7 +451,9 @@ nsDOMStoragePersistentDB::Init(const nsString& aDatabaseName)
|
|||
nsresult
|
||||
nsDOMStoragePersistentDB::EnsureLoadTemporaryTableForStorage(DOMStorageImpl* aStorage)
|
||||
{
|
||||
if (!aStorage->WasTemporaryTableLoaded()) {
|
||||
TimeStamp timeStamp;
|
||||
|
||||
if (!mTempTableLoads.Get(aStorage->GetScopeDBKey(), &timeStamp)) {
|
||||
nsresult rv;
|
||||
|
||||
rv = MaybeCommitInsertTransaction();
|
||||
|
@ -466,57 +473,76 @@ nsDOMStoragePersistentDB::EnsureLoadTemporaryTableForStorage(DOMStorageImpl* aSt
|
|||
|
||||
rv = mCopyToTempTableStatement->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// Always call this to update the last access time
|
||||
aStorage->SetTemporaryTableLoaded(true);
|
||||
mTempTableLoads.Put(aStorage->GetScopeDBKey(), TimeStamp::Now());
|
||||
|
||||
DOMStorageImpl::gStorageDB->EnsureTempTableFlushTimer();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMStoragePersistentDB::FlushAndDeleteTemporaryTableForStorage(DOMStorageImpl* aStorage)
|
||||
/* static */
|
||||
PLDHashOperator
|
||||
nsDOMStoragePersistentDB::FlushTemporaryTable(nsCStringHashKey::KeyType aKey,
|
||||
TimeStamp& aData,
|
||||
void* aUserArg)
|
||||
{
|
||||
if (!aStorage->WasTemporaryTableLoaded())
|
||||
return NS_OK;
|
||||
FlushTemporaryTableData* data = (FlushTemporaryTableData*)aUserArg;
|
||||
|
||||
if (!data->mForce &&
|
||||
((TimeStamp::Now() - aData).ToSeconds() < TEMP_TABLE_MAX_AGE))
|
||||
return PL_DHASH_NEXT;
|
||||
|
||||
{
|
||||
mozStorageStatementScoper scope(data->mDB->mCopyBackToDiskStatement);
|
||||
|
||||
Binder binder(data->mDB->mCopyBackToDiskStatement, &data->mRV);
|
||||
NS_ENSURE_SUCCESS(data->mRV, PL_DHASH_STOP);
|
||||
|
||||
data->mRV = binder->BindUTF8StringByName(NS_LITERAL_CSTRING("scope"), aKey);
|
||||
NS_ENSURE_SUCCESS(data->mRV, PL_DHASH_STOP);
|
||||
|
||||
data->mRV = binder.Add();
|
||||
NS_ENSURE_SUCCESS(data->mRV, PL_DHASH_STOP);
|
||||
|
||||
data->mRV = data->mDB->mCopyBackToDiskStatement->Execute();
|
||||
NS_ENSURE_SUCCESS(data->mRV, PL_DHASH_STOP);
|
||||
}
|
||||
|
||||
{
|
||||
mozStorageStatementScoper scope(data->mDB->mDeleteTemporaryTableStatement);
|
||||
|
||||
Binder binder(data->mDB->mDeleteTemporaryTableStatement, &data->mRV);
|
||||
NS_ENSURE_SUCCESS(data->mRV, PL_DHASH_STOP);
|
||||
|
||||
data->mRV = binder->BindUTF8StringByName(NS_LITERAL_CSTRING("scope"), aKey);
|
||||
NS_ENSURE_SUCCESS(data->mRV, PL_DHASH_STOP);
|
||||
|
||||
data->mRV = binder.Add();
|
||||
NS_ENSURE_SUCCESS(data->mRV, PL_DHASH_STOP);
|
||||
|
||||
data->mRV = data->mDB->mDeleteTemporaryTableStatement->Execute();
|
||||
NS_ENSURE_SUCCESS(data->mRV, PL_DHASH_STOP);
|
||||
}
|
||||
|
||||
return PL_DHASH_REMOVE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMStoragePersistentDB::FlushTemporaryTables(bool force)
|
||||
{
|
||||
mozStorageTransaction trans(mConnection, PR_FALSE);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
{
|
||||
mozStorageStatementScoper scope(mCopyBackToDiskStatement);
|
||||
FlushTemporaryTableData data;
|
||||
data.mDB = this;
|
||||
data.mForce = force;
|
||||
data.mRV = NS_OK;
|
||||
|
||||
Binder binder(mCopyBackToDiskStatement, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = binder->BindUTF8StringByName(NS_LITERAL_CSTRING("scope"),
|
||||
aStorage->GetScopeDBKey());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = binder.Add();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mCopyBackToDiskStatement->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
{
|
||||
mozStorageStatementScoper scope(mDeleteTemporaryTableStatement);
|
||||
|
||||
Binder binder(mDeleteTemporaryTableStatement, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = binder->BindUTF8StringByName(NS_LITERAL_CSTRING("scope"),
|
||||
aStorage->GetScopeDBKey());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = binder.Add();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mDeleteTemporaryTableStatement->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
mTempTableLoads.Enumerate(FlushTemporaryTable, &data);
|
||||
NS_ENSURE_SUCCESS(data.mRV, data.mRV);
|
||||
|
||||
rv = trans.Commit();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -524,8 +550,6 @@ nsDOMStoragePersistentDB::FlushAndDeleteTemporaryTableForStorage(DOMStorageImpl*
|
|||
rv = MaybeCommitInsertTransaction();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aStorage->SetTemporaryTableLoaded(false);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,10 +43,15 @@
|
|||
#include "mozIStorageConnection.h"
|
||||
#include "mozIStorageStatement.h"
|
||||
#include "nsTHashtable.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
||||
class DOMStorageImpl;
|
||||
class nsSessionStorageEntry;
|
||||
|
||||
using mozilla::TimeStamp;
|
||||
using mozilla::TimeDuration;
|
||||
|
||||
class nsDOMStoragePersistentDB
|
||||
{
|
||||
public:
|
||||
|
@ -56,11 +61,6 @@ public:
|
|||
nsresult
|
||||
Init(const nsString& aDatabaseName);
|
||||
|
||||
nsresult
|
||||
EnsureLoadTemporaryTableForStorage(DOMStorageImpl* aStorage);
|
||||
nsresult
|
||||
FlushAndDeleteTemporaryTableForStorage(DOMStorageImpl* aStorage);
|
||||
|
||||
/**
|
||||
* Retrieve a list of all the keys associated with a particular domain.
|
||||
*/
|
||||
|
@ -162,7 +162,26 @@ public:
|
|||
*/
|
||||
nsresult MaybeCommitInsertTransaction();
|
||||
|
||||
/**
|
||||
* Flushes all temporary tables based on time or forcibly during shutdown.
|
||||
*/
|
||||
nsresult FlushTemporaryTables(bool force);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Ensures that a temporary table is correctly filled for the scope of
|
||||
* the given storage.
|
||||
*/
|
||||
nsresult EnsureLoadTemporaryTableForStorage(DOMStorageImpl* aStorage);
|
||||
|
||||
struct FlushTemporaryTableData {
|
||||
nsDOMStoragePersistentDB* mDB;
|
||||
bool mForce;
|
||||
nsresult mRV;
|
||||
};
|
||||
static PLDHashOperator FlushTemporaryTable(nsCStringHashKey::KeyType aKey,
|
||||
TimeStamp& aData,
|
||||
void* aUserArg);
|
||||
|
||||
nsCOMPtr<mozIStorageConnection> mConnection;
|
||||
|
||||
|
@ -183,6 +202,11 @@ protected:
|
|||
nsCString mCachedOwner;
|
||||
PRInt32 mCachedUsage;
|
||||
|
||||
// Maps ScopeDBKey to time of the temporary table load for that scope.
|
||||
// If a record is present, the temp table has been loaded. If it is not
|
||||
// present, the table has not yet been loaded or has alrady been flushed.
|
||||
nsDataHashtable<nsCStringHashKey, TimeStamp> mTempTableLoads;
|
||||
|
||||
friend class nsDOMStorageDBWrapper;
|
||||
friend class nsDOMStorageMemoryDB;
|
||||
nsresult
|
||||
|
|
|
@ -47,6 +47,7 @@ include $(DEPTH)/config/autoconf.mk
|
|||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES = \
|
||||
frameBug624047.html \
|
||||
frameChromeSlave.html \
|
||||
frameMasterEqual.html \
|
||||
frameMasterNotEqual.html \
|
||||
|
@ -61,6 +62,7 @@ _TEST_FILES = \
|
|||
interOriginTest2.js \
|
||||
pbSwitch.js \
|
||||
test_brokenUTF-16.html \
|
||||
test_bug624047.html \
|
||||
test_cookieBlock.html \
|
||||
test_cookieSession-phase1.html \
|
||||
test_cookieSession-phase2.html \
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>slave for bug 624047 test</title>
|
||||
|
||||
<script type="text/javascript" src="interOriginFrame.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
function doStep()
|
||||
{
|
||||
localStorage.name = 1;
|
||||
var timer = setInterval(function() {
|
||||
is(localStorage.name, 1, "Value is still present");
|
||||
}, 1000);
|
||||
|
||||
setTimeout(function() {
|
||||
clearTimeout(timer);
|
||||
localStorage.clear();
|
||||
postMsg("done");
|
||||
}, 12000);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="postMsg('frame loaded');">
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,65 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>bug 624047</title>
|
||||
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="interOriginTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
/*
|
||||
This test does the folliwing:
|
||||
- loads a page in an iframe that stores a value to localStorage
|
||||
- sooner then in 5 seconds reloads the page
|
||||
- now the page later then 5 seconds after load in the first step checks the
|
||||
value is still present in localStorage (what is expected)
|
||||
- if not, the bug is still present
|
||||
*/
|
||||
|
||||
function flushTables()
|
||||
{
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var storageManager = Components.classes["@mozilla.org/dom/storagemanager;1"]
|
||||
.getService(Components.interfaces.nsIObserver);
|
||||
storageManager.observe(null, "profile-before-change", null);
|
||||
}
|
||||
|
||||
function startTest()
|
||||
{
|
||||
slaveOrigin = "http://sub2.test2.example.org";
|
||||
slave = document.getElementById("__test_frame").contentWindow;
|
||||
|
||||
flushTables();
|
||||
slave.location = slaveOrigin + slavePath + "frameBug624047.html";
|
||||
setTimeout(function() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
slaveLoadsPending = 1;
|
||||
slave.location.reload();
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
function doNextTest()
|
||||
{
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function doStep()
|
||||
{
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="startTest();">
|
||||
This test takes about 15s to complete... Please wait...
|
||||
<br/>
|
||||
<iframe src="" id="__test_frame"></iframe>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче