Bug 599978 - Part 2: Asynchronous isVisited checks should use a read-only cloned connection

Changes to create and use the read-only cloned connection.
r=mak
This commit is contained in:
Shawn Wilsher 2010-10-06 08:21:31 -07:00
parent 3fe0fe5fc9
commit 3002b8b720
2 changed files with 67 additions and 13 deletions

View File

@ -170,7 +170,7 @@ public:
// If we are a content process, always remote the request to the // If we are a content process, always remote the request to the
// parent process. // parent process.
if (XRE_GetProcessType() == GeckoProcessType_Content) { if (XRE_GetProcessType() == GeckoProcessType_Content) {
mozilla::dom::ContentChild * cpc = mozilla::dom::ContentChild* cpc =
mozilla::dom::ContentChild::GetSingleton(); mozilla::dom::ContentChild::GetSingleton();
NS_ASSERTION(cpc, "Content Protocol is NULL!"); NS_ASSERTION(cpc, "Content Protocol is NULL!");
(void)cpc->SendStartVisitedQuery(aURI); (void)cpc->SendStartVisitedQuery(aURI);
@ -178,9 +178,8 @@ public:
} }
#endif #endif
nsNavHistory* navHist = nsNavHistory::GetHistoryService(); mozIStorageAsyncStatement* stmt =
NS_ENSURE_TRUE(navHist, NS_ERROR_FAILURE); History::GetService()->GetIsVisitedStatement();
mozIStorageStatement* stmt = navHist->GetStatementById(DB_IS_PAGE_VISITED);
NS_ENSURE_STATE(stmt); NS_ENSURE_STATE(stmt);
// Bind by index for performance. // Bind by index for performance.
@ -260,7 +259,7 @@ class FailSafeFinishTask
{ {
public: public:
FailSafeFinishTask() FailSafeFinishTask()
: mAppended(false) : mAppended(false)
{ {
} }
@ -952,6 +951,37 @@ History::NotifyVisited(nsIURI* aURI)
mObservers.RemoveEntry(aURI); mObservers.RemoveEntry(aURI);
} }
mozIStorageAsyncStatement*
History::GetIsVisitedStatement()
{
if (mIsVisitedStatement) {
return mIsVisitedStatement;
}
// If we don't yet have a database connection, go ahead and clone it now.
if (!mReadOnlyDBConn) {
nsNavHistory* history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, nsnull);
nsCOMPtr<mozIStorageConnection> dbConn;
(void)history->GetDBConnection(getter_AddRefs(dbConn));
NS_ENSURE_TRUE(dbConn, nsnull);
(void)dbConn->Clone(PR_TRUE, getter_AddRefs(mReadOnlyDBConn));
NS_ENSURE_TRUE(mReadOnlyDBConn, nsnull);
}
// Now we can create our cached statement.
nsresult rv = mReadOnlyDBConn->CreateAsyncStatement(NS_LITERAL_CSTRING(
"SELECT h.id "
"FROM moz_places h "
"WHERE url = ?1 "
"AND EXISTS(SELECT id FROM moz_historyvisits WHERE place_id = h.id LIMIT 1) "
), getter_AddRefs(mIsVisitedStatement));
NS_ENSURE_SUCCESS(rv, nsnull);
return mIsVisitedStatement;
}
/* static */ /* static */
History* History*
History::GetService() History::GetService()
@ -1006,6 +1036,10 @@ History::Shutdown()
nsCOMPtr<Step> deadTaskWalking = nsCOMPtr<Step> deadTaskWalking =
dont_AddRef(static_cast<Step*>(mPendingVisits.PopFront())); dont_AddRef(static_cast<Step*>(mPendingVisits.PopFront()));
} }
if (mReadOnlyDBConn) {
(void)mReadOnlyDBConn->AsyncClose(nsnull);
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -48,6 +48,7 @@
#include "nsTArray.h" #include "nsTArray.h"
#include "nsDeque.h" #include "nsDeque.h"
#include "nsIObserver.h" #include "nsIObserver.h"
#include "mozIStorageConnection.h"
namespace mozilla { namespace mozilla {
namespace places { namespace places {
@ -71,7 +72,7 @@ public:
* @param aURI * @param aURI
* The URI to notify about. * The URI to notify about.
*/ */
void NotifyVisited(nsIURI *aURI); void NotifyVisited(nsIURI* aURI);
/** /**
* Append a task to the queue for SQL queries that need to happen * Append a task to the queue for SQL queries that need to happen
@ -93,19 +94,38 @@ public:
*/ */
void CurrentTaskFinished(); void CurrentTaskFinished();
/**
* Obtains the statement to use to check if a URI is visited or not.
*/
mozIStorageAsyncStatement* GetIsVisitedStatement();
/** /**
* Obtains a pointer to this service. * Obtains a pointer to this service.
*/ */
static History *GetService(); static History* GetService();
/** /**
* Obtains a pointer that has had AddRef called on it. Used by the service * Obtains a pointer that has had AddRef called on it. Used by the service
* manager only. * manager only.
*/ */
static History *GetSingleton(); static History* GetSingleton();
private: private:
~History(); virtual ~History();
/**
* A read-only database connection used for checking if a URI is visited.
*
* @note this should only be accessed by GetIsVisistedStatement and Shutdown.
*/
nsCOMPtr<mozIStorageConnection> mReadOnlyDBConn;
/**
* An asynchronous statement to query if a URI is visited or not.
*
* @note this should only be accessed by GetIsVisistedStatement.
*/
nsCOMPtr<mozIStorageAsyncStatement> mIsVisitedStatement;
/** /**
* Since visits rapidly fire at once, it's very likely to have race * Since visits rapidly fire at once, it's very likely to have race
@ -132,21 +152,21 @@ private:
*/ */
void Shutdown(); void Shutdown();
static History *gService; static History* gService;
// Ensures new tasks aren't started on destruction. // Ensures new tasks aren't started on destruction.
bool mShuttingDown; bool mShuttingDown;
typedef nsTArray<mozilla::dom::Link *> ObserverArray; typedef nsTArray<mozilla::dom::Link* > ObserverArray;
class KeyClass : public nsURIHashKey class KeyClass : public nsURIHashKey
{ {
public: public:
KeyClass(const nsIURI *aURI) KeyClass(const nsIURI* aURI)
: nsURIHashKey(aURI) : nsURIHashKey(aURI)
{ {
} }
KeyClass(const KeyClass &aOther) KeyClass(const KeyClass& aOther)
: nsURIHashKey(aOther) : nsURIHashKey(aOther)
{ {
NS_NOTREACHED("Do not call me!"); NS_NOTREACHED("Do not call me!");