Bug 998330 - MinimizeMemory should happen on the opener thread, not on main-thread. r=asuth

This commit is contained in:
Marco Bonardo 2015-01-28 00:00:23 +01:00
Родитель 1e36234414
Коммит b04ae3b1d2
2 изменённых файлов: 38 добавлений и 14 удалений

Просмотреть файл

@ -51,6 +51,19 @@
PRLogModuleInfo* gStorageLog = nullptr;
#endif
// Checks that the protected code is running on the main-thread only if the
// connection was also opened on it.
#ifdef DEBUG
#define CHECK_MAINTHREAD_ABUSE() \
do { \
nsCOMPtr<nsIThread> mainThread = do_GetMainThread(); \
NS_WARN_IF_FALSE(threadOpenedOn == mainThread || !NS_IsMainThread(), \
"Using Storage synchronous API on main-thread, but the connection was opened on another thread."); \
} while(0)
#else
#define CHECK_MAINTHREAD_ABUSE() do { /* Nothing */ } while(0)
#endif
namespace mozilla {
namespace storage {
@ -1422,6 +1435,7 @@ Connection::CreateAsyncStatement(const nsACString &aSQLStatement,
NS_IMETHODIMP
Connection::ExecuteSimpleSQL(const nsACString &aSQLStatement)
{
CHECK_MAINTHREAD_ABUSE();
if (!mDBConn) return NS_ERROR_NOT_INITIALIZED;
int srv = executeSql(mDBConn, PromiseFlatCString(aSQLStatement).get());

Просмотреть файл

@ -347,22 +347,32 @@ Service::minimizeMemory()
for (uint32_t i = 0; i < connections.Length(); i++) {
nsRefPtr<Connection> conn = connections[i];
if (conn->connectionReady()) {
NS_NAMED_LITERAL_CSTRING(shrinkPragma, "PRAGMA shrink_memory");
nsCOMPtr<mozIStorageConnection> syncConn = do_QueryInterface(
NS_ISUPPORTS_CAST(mozIStorageAsyncConnection*, conn));
DebugOnly<nsresult> rv;
if (!conn->connectionReady())
continue;
if (!syncConn) {
nsCOMPtr<mozIStoragePendingStatement> ps;
rv = connections[i]->ExecuteSimpleSQLAsync(shrinkPragma, nullptr,
getter_AddRefs(ps));
} else {
rv = connections[i]->ExecuteSimpleSQL(shrinkPragma);
}
NS_NAMED_LITERAL_CSTRING(shrinkPragma, "PRAGMA shrink_memory");
nsCOMPtr<mozIStorageConnection> syncConn = do_QueryInterface(
NS_ISUPPORTS_CAST(mozIStorageAsyncConnection*, conn));
bool onOpenedThread = false;
MOZ_ASSERT(NS_SUCCEEDED(rv),
"Should have been able to purge sqlite caches");
if (!syncConn) {
// This is a mozIStorageAsyncConnection, it can only be used on the main
// thread, so we can do a straight API call.
nsCOMPtr<mozIStoragePendingStatement> ps;
DebugOnly<nsresult> rv =
conn->ExecuteSimpleSQLAsync(shrinkPragma, nullptr, getter_AddRefs(ps));
MOZ_ASSERT(NS_SUCCEEDED(rv), "Should have purged sqlite caches");
} else if (NS_SUCCEEDED(conn->threadOpenedOn->IsOnCurrentThread(&onOpenedThread)) &&
onOpenedThread) {
// We are on the opener thread, so we can just proceed.
conn->ExecuteSimpleSQL(shrinkPragma);
} else {
// We are on the wrong thread, the query should be executed on the
// opener thread, so we must dispatch to it.
nsCOMPtr<nsIRunnable> event =
NS_NewRunnableMethodWithArg<const nsCString>(
conn, &Connection::ExecuteSimpleSQL, shrinkPragma);
conn->threadOpenedOn->Dispatch(event, NS_DISPATCH_NORMAL);
}
}
}