зеркало из 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, "profile-after-change", PR_FALSE);
|
||||||
os->AddObserver(gStorageManager, "perm-changed", PR_FALSE);
|
os->AddObserver(gStorageManager, "perm-changed", PR_FALSE);
|
||||||
os->AddObserver(gStorageManager, "browser:purge-domain-data", 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;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -441,8 +447,6 @@ nsDOMStorageManager::Observe(nsISupports *aSubject,
|
||||||
nsCOMPtr<nsIObserverService> obsserv = mozilla::services::GetObserverService();
|
nsCOMPtr<nsIObserverService> obsserv = mozilla::services::GetObserverService();
|
||||||
if (obsserv)
|
if (obsserv)
|
||||||
obsserv->NotifyObservers(nsnull, NS_DOMSTORAGE_FLUSH_TIMER_OBSERVER, nsnull);
|
obsserv->NotifyObservers(nsnull, NS_DOMSTORAGE_FLUSH_TIMER_OBSERVER, nsnull);
|
||||||
if (!UnflushedDataExists())
|
|
||||||
DOMStorageImpl::gStorageDB->StopTempTableFlushTimer();
|
|
||||||
} else if (!strcmp(aTopic, "browser:purge-domain-data")) {
|
} else if (!strcmp(aTopic, "browser:purge-domain-data")) {
|
||||||
// Convert the domain name to the ACE format
|
// Convert the domain name to the ACE format
|
||||||
nsCAutoString aceDomain;
|
nsCAutoString aceDomain;
|
||||||
|
@ -470,6 +474,19 @@ nsDOMStorageManager::Observe(nsISupports *aSubject,
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
DOMStorageImpl::gStorageDB->RemoveOwner(aceDomain, PR_TRUE);
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,26 +556,6 @@ nsDOMStorageManager::RemoveFromStoragesHash(DOMStorageImpl* aStorage)
|
||||||
mStorages.RemoveEntry(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
|
// nsDOMStorage
|
||||||
//
|
//
|
||||||
|
@ -726,25 +723,19 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMStorageImpl)
|
||||||
}
|
}
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(DOMStorageImpl, nsIObserver)
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMStorageImpl)
|
||||||
NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(DOMStorageImpl, nsIObserver)
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMStorageImpl)
|
||||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMStorageImpl)
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMStorageImpl)
|
||||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver)
|
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
|
||||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
|
||||||
NS_INTERFACE_MAP_END
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
DOMStorageImpl::DOMStorageImpl(nsDOMStorage* aStorage)
|
DOMStorageImpl::DOMStorageImpl(nsDOMStorage* aStorage)
|
||||||
: mLoadedTemporaryTable(false)
|
|
||||||
{
|
{
|
||||||
Init(aStorage);
|
Init(aStorage);
|
||||||
}
|
}
|
||||||
|
|
||||||
DOMStorageImpl::DOMStorageImpl(nsDOMStorage* aStorage, DOMStorageImpl& aThat)
|
DOMStorageImpl::DOMStorageImpl(nsDOMStorage* aStorage, DOMStorageImpl& aThat)
|
||||||
: DOMStorageBase(aThat)
|
: DOMStorageBase(aThat)
|
||||||
, mLoadedTemporaryTable(aThat.mLoadedTemporaryTable)
|
|
||||||
, mLastTemporaryTableAccessTime(aThat.mLastTemporaryTableAccessTime)
|
|
||||||
, mTemporaryTableAge(aThat.mTemporaryTableAge)
|
|
||||||
{
|
{
|
||||||
Init(aStorage);
|
Init(aStorage);
|
||||||
}
|
}
|
||||||
|
@ -807,8 +798,6 @@ DOMStorageImpl::InitFromChild(bool aUseDB, bool aCanUseChromePersist,
|
||||||
mQuotaDomainDBKey = aQuotaDomainDBKey;
|
mQuotaDomainDBKey = aQuotaDomainDBKey;
|
||||||
mQuotaETLDplus1DomainDBKey = aQuotaETLDplus1DomainDBKey;
|
mQuotaETLDplus1DomainDBKey = aQuotaETLDplus1DomainDBKey;
|
||||||
mStorageType = static_cast<nsPIDOMStorage::nsDOMStorageType>(aStorageType);
|
mStorageType = static_cast<nsPIDOMStorage::nsDOMStorageType>(aStorageType);
|
||||||
if (mStorageType != nsPIDOMStorage::SessionStorage)
|
|
||||||
RegisterObservers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -828,14 +817,12 @@ DOMStorageImpl::InitAsLocalStorage(nsIURI* aDomainURI,
|
||||||
bool aCanUseChromePersist)
|
bool aCanUseChromePersist)
|
||||||
{
|
{
|
||||||
DOMStorageBase::InitAsLocalStorage(aDomainURI, aCanUseChromePersist);
|
DOMStorageBase::InitAsLocalStorage(aDomainURI, aCanUseChromePersist);
|
||||||
RegisterObservers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DOMStorageImpl::InitAsGlobalStorage(const nsACString& aDomainDemanded)
|
DOMStorageImpl::InitAsGlobalStorage(const nsACString& aDomainDemanded)
|
||||||
{
|
{
|
||||||
DOMStorageBase::InitAsGlobalStorage(aDomainDemanded);
|
DOMStorageBase::InitAsGlobalStorage(aDomainDemanded);
|
||||||
RegisterObservers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -1032,86 +1019,6 @@ DOMStorageImpl::CloneFrom(bool aCallerSecure, DOMStorageBase* aThat)
|
||||||
return NS_OK;
|
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
|
nsresult
|
||||||
DOMStorageImpl::CacheKeysFromDB()
|
DOMStorageImpl::CacheKeysFromDB()
|
||||||
{
|
{
|
||||||
|
|
|
@ -61,7 +61,6 @@
|
||||||
#include "nsIObserver.h"
|
#include "nsIObserver.h"
|
||||||
#include "nsITimer.h"
|
#include "nsITimer.h"
|
||||||
#include "nsWeakReference.h"
|
#include "nsWeakReference.h"
|
||||||
#include "mozilla/TimeStamp.h"
|
|
||||||
|
|
||||||
#define NS_DOMSTORAGE_FLUSH_TIMER_OBSERVER "domstorage-flush-timer"
|
#define NS_DOMSTORAGE_FLUSH_TIMER_OBSERVER "domstorage-flush-timer"
|
||||||
|
|
||||||
|
@ -76,9 +75,7 @@
|
||||||
class nsDOMStorage;
|
class nsDOMStorage;
|
||||||
class nsIDOMStorage;
|
class nsIDOMStorage;
|
||||||
class nsDOMStorageItem;
|
class nsDOMStorageItem;
|
||||||
|
class nsDOMStoragePersistentDB;
|
||||||
using mozilla::TimeStamp;
|
|
||||||
using mozilla::TimeDuration;
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
@ -244,14 +241,11 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
class DOMStorageImpl : public DOMStorageBase
|
class DOMStorageImpl : public DOMStorageBase
|
||||||
, public nsIObserver
|
|
||||||
, public nsSupportsWeakReference
|
|
||||||
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(DOMStorageImpl, nsIObserver)
|
NS_DECL_CYCLE_COLLECTION_CLASS(DOMStorageImpl)
|
||||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
NS_DECL_NSIOBSERVER
|
|
||||||
|
|
||||||
DOMStorageImpl(nsDOMStorage*);
|
DOMStorageImpl(nsDOMStorage*);
|
||||||
DOMStorageImpl(nsDOMStorage*, DOMStorageImpl&);
|
DOMStorageImpl(nsDOMStorage*, DOMStorageImpl&);
|
||||||
|
@ -314,12 +308,6 @@ public:
|
||||||
virtual nsresult
|
virtual nsresult
|
||||||
CloneFrom(bool aCallerSecure, DOMStorageBase* aThat);
|
CloneFrom(bool aCallerSecure, DOMStorageBase* aThat);
|
||||||
|
|
||||||
nsresult RegisterObservers();
|
|
||||||
nsresult MaybeCommitTemporaryTable(bool force);
|
|
||||||
|
|
||||||
bool WasTemporaryTableLoaded();
|
|
||||||
void SetTemporaryTableLoaded(bool loaded);
|
|
||||||
|
|
||||||
virtual bool CacheStoragePermissions();
|
virtual bool CacheStoragePermissions();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -327,6 +315,7 @@ private:
|
||||||
static nsDOMStorageDBWrapper* gStorageDB;
|
static nsDOMStorageDBWrapper* gStorageDB;
|
||||||
#endif
|
#endif
|
||||||
friend class nsDOMStorageManager;
|
friend class nsDOMStorageManager;
|
||||||
|
friend class nsDOMStoragePersistentDB;
|
||||||
friend class StorageParent;
|
friend class StorageParent;
|
||||||
|
|
||||||
void Init(nsDOMStorage*);
|
void Init(nsDOMStorage*);
|
||||||
|
@ -351,10 +340,6 @@ private:
|
||||||
|
|
||||||
// Weak reference to the owning storage instance
|
// Weak reference to the owning storage instance
|
||||||
nsDOMStorage* mOwner;
|
nsDOMStorage* mOwner;
|
||||||
|
|
||||||
bool mLoadedTemporaryTable;
|
|
||||||
TimeStamp mLastTemporaryTableAccessTime;
|
|
||||||
TimeStamp mTemporaryTableAge;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class nsDOMStorage : public nsIDOMStorageObsolete,
|
class nsDOMStorage : public nsIDOMStorageObsolete,
|
||||||
|
|
|
@ -75,7 +75,6 @@ nsDOMStorageDBWrapper::nsDOMStorageDBWrapper()
|
||||||
|
|
||||||
nsDOMStorageDBWrapper::~nsDOMStorageDBWrapper()
|
nsDOMStorageDBWrapper::~nsDOMStorageDBWrapper()
|
||||||
{
|
{
|
||||||
StopTempTableFlushTimer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -99,29 +98,18 @@ nsDOMStorageDBWrapper::Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsDOMStorageDBWrapper::EnsureLoadTemporaryTableForStorage(DOMStorageImpl* aStorage)
|
nsDOMStorageDBWrapper::FlushAndDeleteTemporaryTables(bool force)
|
||||||
{
|
{
|
||||||
if (aStorage->CanUseChromePersist())
|
nsresult rv1, rv2;
|
||||||
return mChromePersistentDB.EnsureLoadTemporaryTableForStorage(aStorage);
|
rv1 = mChromePersistentDB.FlushTemporaryTables(force);
|
||||||
if (nsDOMStorageManager::gStorageManager->InPrivateBrowsingMode())
|
rv2 = mPersistentDB.FlushTemporaryTables(force);
|
||||||
return NS_OK;
|
|
||||||
if (aStorage->SessionOnly())
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
return mPersistentDB.EnsureLoadTemporaryTableForStorage(aStorage);
|
// Everything flushed? Then no need for a timer.
|
||||||
}
|
if (!mChromePersistentDB.mTempTableLoads.Count() &&
|
||||||
|
!mPersistentDB.mTempTableLoads.Count())
|
||||||
|
StopTempTableFlushTimer();
|
||||||
|
|
||||||
nsresult
|
return NS_FAILED(rv1) ? rv1 : rv2;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
|
|
@ -92,11 +92,6 @@ public:
|
||||||
nsresult
|
nsresult
|
||||||
Init();
|
Init();
|
||||||
|
|
||||||
nsresult
|
|
||||||
EnsureLoadTemporaryTableForStorage(DOMStorageImpl* aStorage);
|
|
||||||
nsresult
|
|
||||||
FlushAndDeleteTemporaryTableForStorage(DOMStorageImpl* aStorage);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a list of all the keys associated with a particular domain.
|
* Retrieve a list of all the keys associated with a particular domain.
|
||||||
*/
|
*/
|
||||||
|
@ -227,6 +222,14 @@ public:
|
||||||
*/
|
*/
|
||||||
void EnsureTempTableFlushTimer();
|
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.
|
* Stops the temp table flush timer.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -55,6 +55,10 @@
|
||||||
#include "nsPrintfCString.h"
|
#include "nsPrintfCString.h"
|
||||||
#include "nsNetUtil.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
|
class nsReverseStringSQLFunction : public mozIStorageFunction
|
||||||
{
|
{
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
@ -98,6 +102,7 @@ NS_IMPL_ISUPPORTS1(nsIsOfflineSQLFunction, mozIStorageFunction)
|
||||||
|
|
||||||
nsDOMStoragePersistentDB::nsDOMStoragePersistentDB()
|
nsDOMStoragePersistentDB::nsDOMStoragePersistentDB()
|
||||||
{
|
{
|
||||||
|
mTempTableLoads.Init(16);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -446,7 +451,9 @@ nsDOMStoragePersistentDB::Init(const nsString& aDatabaseName)
|
||||||
nsresult
|
nsresult
|
||||||
nsDOMStoragePersistentDB::EnsureLoadTemporaryTableForStorage(DOMStorageImpl* aStorage)
|
nsDOMStoragePersistentDB::EnsureLoadTemporaryTableForStorage(DOMStorageImpl* aStorage)
|
||||||
{
|
{
|
||||||
if (!aStorage->WasTemporaryTableLoaded()) {
|
TimeStamp timeStamp;
|
||||||
|
|
||||||
|
if (!mTempTableLoads.Get(aStorage->GetScopeDBKey(), &timeStamp)) {
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
rv = MaybeCommitInsertTransaction();
|
rv = MaybeCommitInsertTransaction();
|
||||||
|
@ -466,57 +473,76 @@ nsDOMStoragePersistentDB::EnsureLoadTemporaryTableForStorage(DOMStorageImpl* aSt
|
||||||
|
|
||||||
rv = mCopyToTempTableStatement->Execute();
|
rv = mCopyToTempTableStatement->Execute();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
|
||||||
|
|
||||||
// Always call this to update the last access time
|
mTempTableLoads.Put(aStorage->GetScopeDBKey(), TimeStamp::Now());
|
||||||
aStorage->SetTemporaryTableLoaded(true);
|
|
||||||
|
DOMStorageImpl::gStorageDB->EnsureTempTableFlushTimer();
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
/* static */
|
||||||
nsDOMStoragePersistentDB::FlushAndDeleteTemporaryTableForStorage(DOMStorageImpl* aStorage)
|
PLDHashOperator
|
||||||
|
nsDOMStoragePersistentDB::FlushTemporaryTable(nsCStringHashKey::KeyType aKey,
|
||||||
|
TimeStamp& aData,
|
||||||
|
void* aUserArg)
|
||||||
{
|
{
|
||||||
if (!aStorage->WasTemporaryTableLoaded())
|
FlushTemporaryTableData* data = (FlushTemporaryTableData*)aUserArg;
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
|
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);
|
mozStorageTransaction trans(mConnection, PR_FALSE);
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
{
|
FlushTemporaryTableData data;
|
||||||
mozStorageStatementScoper scope(mCopyBackToDiskStatement);
|
data.mDB = this;
|
||||||
|
data.mForce = force;
|
||||||
|
data.mRV = NS_OK;
|
||||||
|
|
||||||
Binder binder(mCopyBackToDiskStatement, &rv);
|
mTempTableLoads.Enumerate(FlushTemporaryTable, &data);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(data.mRV, data.mRV);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = trans.Commit();
|
rv = trans.Commit();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
@ -524,8 +550,6 @@ nsDOMStoragePersistentDB::FlushAndDeleteTemporaryTableForStorage(DOMStorageImpl*
|
||||||
rv = MaybeCommitInsertTransaction();
|
rv = MaybeCommitInsertTransaction();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
aStorage->SetTemporaryTableLoaded(false);
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,10 +43,15 @@
|
||||||
#include "mozIStorageConnection.h"
|
#include "mozIStorageConnection.h"
|
||||||
#include "mozIStorageStatement.h"
|
#include "mozIStorageStatement.h"
|
||||||
#include "nsTHashtable.h"
|
#include "nsTHashtable.h"
|
||||||
|
#include "nsDataHashtable.h"
|
||||||
|
#include "mozilla/TimeStamp.h"
|
||||||
|
|
||||||
class DOMStorageImpl;
|
class DOMStorageImpl;
|
||||||
class nsSessionStorageEntry;
|
class nsSessionStorageEntry;
|
||||||
|
|
||||||
|
using mozilla::TimeStamp;
|
||||||
|
using mozilla::TimeDuration;
|
||||||
|
|
||||||
class nsDOMStoragePersistentDB
|
class nsDOMStoragePersistentDB
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -56,11 +61,6 @@ public:
|
||||||
nsresult
|
nsresult
|
||||||
Init(const nsString& aDatabaseName);
|
Init(const nsString& aDatabaseName);
|
||||||
|
|
||||||
nsresult
|
|
||||||
EnsureLoadTemporaryTableForStorage(DOMStorageImpl* aStorage);
|
|
||||||
nsresult
|
|
||||||
FlushAndDeleteTemporaryTableForStorage(DOMStorageImpl* aStorage);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a list of all the keys associated with a particular domain.
|
* Retrieve a list of all the keys associated with a particular domain.
|
||||||
*/
|
*/
|
||||||
|
@ -162,7 +162,26 @@ public:
|
||||||
*/
|
*/
|
||||||
nsresult MaybeCommitInsertTransaction();
|
nsresult MaybeCommitInsertTransaction();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flushes all temporary tables based on time or forcibly during shutdown.
|
||||||
|
*/
|
||||||
|
nsresult FlushTemporaryTables(bool force);
|
||||||
|
|
||||||
protected:
|
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;
|
nsCOMPtr<mozIStorageConnection> mConnection;
|
||||||
|
|
||||||
|
@ -183,6 +202,11 @@ protected:
|
||||||
nsCString mCachedOwner;
|
nsCString mCachedOwner;
|
||||||
PRInt32 mCachedUsage;
|
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 nsDOMStorageDBWrapper;
|
||||||
friend class nsDOMStorageMemoryDB;
|
friend class nsDOMStorageMemoryDB;
|
||||||
nsresult
|
nsresult
|
||||||
|
|
|
@ -47,6 +47,7 @@ include $(DEPTH)/config/autoconf.mk
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
|
||||||
_TEST_FILES = \
|
_TEST_FILES = \
|
||||||
|
frameBug624047.html \
|
||||||
frameChromeSlave.html \
|
frameChromeSlave.html \
|
||||||
frameMasterEqual.html \
|
frameMasterEqual.html \
|
||||||
frameMasterNotEqual.html \
|
frameMasterNotEqual.html \
|
||||||
|
@ -61,6 +62,7 @@ _TEST_FILES = \
|
||||||
interOriginTest2.js \
|
interOriginTest2.js \
|
||||||
pbSwitch.js \
|
pbSwitch.js \
|
||||||
test_brokenUTF-16.html \
|
test_brokenUTF-16.html \
|
||||||
|
test_bug624047.html \
|
||||||
test_cookieBlock.html \
|
test_cookieBlock.html \
|
||||||
test_cookieSession-phase1.html \
|
test_cookieSession-phase1.html \
|
||||||
test_cookieSession-phase2.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>
|
Загрузка…
Ссылка в новой задаче