mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 14:52:16 +00:00
Bug 1638256 - Use mTelemetryFilename for the mozStorage thread name. r=asuth
Depends on D181037 Differential Revision: https://phabricator.services.mozilla.com/D181038
This commit is contained in:
parent
81f54fd826
commit
95fe144ede
@ -18,6 +18,21 @@ interface nsIPropertyBag2;
|
||||
interface nsIVariant;
|
||||
interface mozIStorageCompletionCallback;
|
||||
|
||||
/**
|
||||
* PRIVACY WARNING
|
||||
* ===============
|
||||
*
|
||||
* Database file names can be exposed through telemetry and in crash reports on
|
||||
* the https://crash-stats.mozilla.org site, to allow recognizing the affected
|
||||
* database.
|
||||
* if your database name may contain privacy sensitive information, e.g. an
|
||||
* URL origin, you should use openDatabaseWithFileURL and pass an explicit
|
||||
* TelemetryFilename to it. That name will be used both for telemetry and for
|
||||
* thread names in crash reports.
|
||||
* If you have different needs (e.g. using the javascript module or an async
|
||||
* connection from the main thread) please coordinate with the mozStorage peers.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The mozIStorageService interface is intended to be implemented by
|
||||
* a service that can create storage connections (mozIStorageConnection)
|
||||
|
@ -707,8 +707,15 @@ nsIEventTarget* Connection::getAsyncExecutionTarget() {
|
||||
|
||||
// Create the async event target if there's none yet.
|
||||
if (!mAsyncExecutionThread) {
|
||||
// Names start with "sqldb:" followed by a recognizable name, like the
|
||||
// database file name, or a specially crafted name like "memory".
|
||||
// This name will be surfaced on https://crash-stats.mozilla.org, so any
|
||||
// sensitive part of the file name (e.g. an URL origin) should be replaced
|
||||
// by passing an explicit telemetryName to openDatabaseWithFileURL.
|
||||
nsAutoCString name("sqldb:"_ns);
|
||||
name.Append(mTelemetryFilename);
|
||||
static nsThreadPoolNaming naming;
|
||||
nsresult rv = NS_NewNamedThread(naming.GetNextThreadName("mozStorage"),
|
||||
nsresult rv = NS_NewNamedThread(naming.GetNextThreadName(name),
|
||||
getter_AddRefs(mAsyncExecutionThread));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to create async thread.");
|
||||
|
@ -467,8 +467,9 @@ Service::OpenSpecialDatabase(const nsACString& aStorageKey,
|
||||
flags |= SQLITE_OPEN_URI;
|
||||
}
|
||||
|
||||
RefPtr<Connection> msc = new Connection(this, flags, Connection::SYNCHRONOUS,
|
||||
":memory:"_ns, interruptible);
|
||||
RefPtr<Connection> msc =
|
||||
new Connection(this, flags, Connection::SYNCHRONOUS,
|
||||
kMozStorageMemoryStorageKey, interruptible);
|
||||
const nsresult rv = msc->initialize(aStorageKey, aName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@ -589,7 +590,7 @@ Service::OpenAsyncDatabase(nsIVariant* aDatabaseStore, uint32_t aOpenFlags,
|
||||
// Create connection on this thread, but initialize it on its helper thread.
|
||||
nsAutoCString telemetryFilename;
|
||||
if (!storageFile) {
|
||||
telemetryFilename.AssignLiteral("memory");
|
||||
telemetryFilename.Assign(kMozStorageMemoryStorageKey);
|
||||
} else {
|
||||
rv = storageFile->GetNativeLeafName(telemetryFilename);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -8,6 +8,7 @@ UNIFIED_SOURCES += [
|
||||
"storage_test_harness.cpp",
|
||||
"test_AsXXX_helpers.cpp",
|
||||
"test_async_callbacks_with_spun_event_loops.cpp",
|
||||
"test_async_thread_naming.cpp",
|
||||
"test_asyncStatementExecution_transaction.cpp",
|
||||
"test_binding_params.cpp",
|
||||
"test_file_perms.cpp",
|
||||
|
@ -105,6 +105,28 @@ void AsyncStatementSpinner::SpinUntilCompleted() {
|
||||
#define NS_DECL_ASYNCSTATEMENTSPINNER \
|
||||
NS_IMETHOD HandleResult(mozIStorageResultSet* aResultSet) override;
|
||||
|
||||
NS_IMPL_ISUPPORTS(AsyncCompletionSpinner, mozIStorageCompletionCallback)
|
||||
|
||||
AsyncCompletionSpinner::AsyncCompletionSpinner()
|
||||
: mCompletionReason(NS_OK), mCompleted(false) {}
|
||||
|
||||
NS_IMETHODIMP
|
||||
AsyncCompletionSpinner::Complete(nsresult reason, nsISupports* value) {
|
||||
mCompleted = true;
|
||||
mCompletionReason = reason;
|
||||
mCompletionValue = value;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void AsyncCompletionSpinner::SpinUntilCompleted() {
|
||||
nsCOMPtr<nsIThread> thread(::do_GetCurrentThread());
|
||||
nsresult rv = NS_OK;
|
||||
bool processed = true;
|
||||
while (!mCompleted && NS_SUCCEEDED(rv)) {
|
||||
rv = thread->ProcessNextEvent(true, &processed);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Async Helpers
|
||||
|
||||
|
@ -66,7 +66,24 @@ class AsyncStatementSpinner : public mozIStorageStatementCallback,
|
||||
uint16_t completionReason;
|
||||
|
||||
protected:
|
||||
virtual ~AsyncStatementSpinner() {}
|
||||
virtual ~AsyncStatementSpinner() = default;
|
||||
volatile bool mCompleted;
|
||||
};
|
||||
|
||||
class AsyncCompletionSpinner : public mozIStorageCompletionCallback {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_MOZISTORAGECOMPLETIONCALLBACK
|
||||
|
||||
AsyncCompletionSpinner();
|
||||
|
||||
void SpinUntilCompleted();
|
||||
|
||||
nsresult mCompletionReason;
|
||||
nsCOMPtr<nsISupports> mCompletionValue;
|
||||
|
||||
protected:
|
||||
virtual ~AsyncCompletionSpinner() = default;
|
||||
volatile bool mCompleted;
|
||||
};
|
||||
|
||||
|
230
storage/test/gtest/test_async_thread_naming.cpp
Normal file
230
storage/test/gtest/test_async_thread_naming.cpp
Normal file
@ -0,0 +1,230 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
|
||||
* 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/. */
|
||||
|
||||
#include "nsVariant.h"
|
||||
#include "storage_test_harness.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIFileURL.h"
|
||||
#include "nsIVariant.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Tests
|
||||
|
||||
TEST(storage_async_thread_naming, MemoryDatabase)
|
||||
{
|
||||
HookSqliteMutex hook;
|
||||
|
||||
nsCOMPtr<mozIStorageConnection> db(getMemoryDatabase());
|
||||
|
||||
nsCOMPtr<nsIThread> target(get_conn_async_thread(db));
|
||||
do_check_true(target);
|
||||
PRThread* prThread;
|
||||
target->GetPRThread(&prThread);
|
||||
do_check_true(prThread);
|
||||
nsAutoCString name(PR_GetThreadName(prThread));
|
||||
printf("%s", name.get());
|
||||
do_check_true(StringBeginsWith(name, "sqldb:memory"_ns));
|
||||
|
||||
blocking_async_close(db);
|
||||
}
|
||||
|
||||
TEST(storage_async_thread_naming, FileDatabase)
|
||||
{
|
||||
HookSqliteMutex hook;
|
||||
|
||||
nsAutoString filename(u"test_thread_name.sqlite"_ns);
|
||||
nsCOMPtr<nsIFile> dbFile;
|
||||
do_check_success(NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
|
||||
getter_AddRefs(dbFile)));
|
||||
do_check_success(dbFile->Append(filename));
|
||||
nsCOMPtr<mozIStorageService> ss = getService();
|
||||
nsCOMPtr<mozIStorageConnection> conn;
|
||||
do_check_success(ss->OpenDatabase(dbFile, 0, getter_AddRefs(conn)));
|
||||
|
||||
nsCOMPtr<nsIThread> target(get_conn_async_thread(conn));
|
||||
do_check_true(target);
|
||||
PRThread* prThread;
|
||||
target->GetPRThread(&prThread);
|
||||
do_check_true(prThread);
|
||||
nsAutoCString name(PR_GetThreadName(prThread));
|
||||
nsAutoCString expected("sqldb:"_ns);
|
||||
expected.Append(NS_ConvertUTF16toUTF8(filename));
|
||||
do_check_true(StringBeginsWith(name, expected));
|
||||
|
||||
{
|
||||
nsCOMPtr<mozIStorageConnection> clone;
|
||||
do_check_success(conn->Clone(true, getter_AddRefs(clone)));
|
||||
nsCOMPtr<nsIThread> target(get_conn_async_thread(conn));
|
||||
do_check_true(target);
|
||||
PRThread* prThread;
|
||||
target->GetPRThread(&prThread);
|
||||
do_check_true(prThread);
|
||||
nsAutoCString name(PR_GetThreadName(prThread));
|
||||
nsAutoCString expected("sqldb:"_ns);
|
||||
expected.Append(NS_ConvertUTF16toUTF8(filename));
|
||||
do_check_true(StringBeginsWith(name, expected));
|
||||
blocking_async_close(clone);
|
||||
}
|
||||
|
||||
blocking_async_close(conn);
|
||||
}
|
||||
|
||||
TEST(storage_async_thread_naming, FileUnsharedDatabase)
|
||||
{
|
||||
HookSqliteMutex hook;
|
||||
|
||||
nsAutoString filename(u"test_thread_name.sqlite"_ns);
|
||||
nsCOMPtr<nsIFile> dbFile;
|
||||
do_check_success(NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
|
||||
getter_AddRefs(dbFile)));
|
||||
do_check_success(dbFile->Append(filename));
|
||||
nsCOMPtr<mozIStorageService> ss = getService();
|
||||
nsCOMPtr<mozIStorageConnection> conn;
|
||||
do_check_success(ss->OpenUnsharedDatabase(dbFile, 0, getter_AddRefs(conn)));
|
||||
|
||||
nsCOMPtr<nsIThread> target(get_conn_async_thread(conn));
|
||||
do_check_true(target);
|
||||
PRThread* prThread;
|
||||
target->GetPRThread(&prThread);
|
||||
do_check_true(prThread);
|
||||
nsAutoCString name(PR_GetThreadName(prThread));
|
||||
nsAutoCString expected("sqldb:"_ns);
|
||||
expected.Append(NS_ConvertUTF16toUTF8(filename));
|
||||
do_check_true(StringBeginsWith(name, expected));
|
||||
|
||||
blocking_async_close(conn);
|
||||
}
|
||||
|
||||
TEST(storage_async_thread_naming, FileURLDatabase)
|
||||
{
|
||||
HookSqliteMutex hook;
|
||||
|
||||
nsAutoString filename(u"test_thread_name.sqlite"_ns);
|
||||
nsCOMPtr<nsIFile> dbFile;
|
||||
do_check_success(NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
|
||||
getter_AddRefs(dbFile)));
|
||||
do_check_success(dbFile->Append(filename));
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
do_check_success(NS_NewFileURI(getter_AddRefs(uri), dbFile));
|
||||
nsCOMPtr<nsIFileURL> fileUrl = do_QueryInterface(uri);
|
||||
nsCOMPtr<mozIStorageService> ss = getService();
|
||||
nsCOMPtr<mozIStorageConnection> conn;
|
||||
do_check_success(ss->OpenDatabaseWithFileURL(fileUrl, EmptyCString(), 0,
|
||||
getter_AddRefs(conn)));
|
||||
|
||||
nsCOMPtr<nsIThread> target(get_conn_async_thread(conn));
|
||||
do_check_true(target);
|
||||
PRThread* prThread;
|
||||
target->GetPRThread(&prThread);
|
||||
do_check_true(prThread);
|
||||
nsAutoCString name(PR_GetThreadName(prThread));
|
||||
nsAutoCString expected("sqldb:"_ns);
|
||||
expected.Append(NS_ConvertUTF16toUTF8(filename));
|
||||
do_check_true(StringBeginsWith(name, expected));
|
||||
|
||||
blocking_async_close(conn);
|
||||
}
|
||||
|
||||
TEST(storage_async_thread_naming, OverrideFileURLDatabase)
|
||||
{
|
||||
HookSqliteMutex hook;
|
||||
|
||||
nsAutoString filename(u"test_thread_name.sqlite"_ns);
|
||||
nsCOMPtr<nsIFile> dbFile;
|
||||
do_check_success(NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
|
||||
getter_AddRefs(dbFile)));
|
||||
do_check_success(dbFile->Append(filename));
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
do_check_success(NS_NewFileURI(getter_AddRefs(uri), dbFile));
|
||||
nsCOMPtr<nsIFileURL> fileUrl = do_QueryInterface(uri);
|
||||
nsCOMPtr<mozIStorageService> ss = getService();
|
||||
nsCOMPtr<mozIStorageConnection> conn;
|
||||
nsAutoCString override("override"_ns);
|
||||
do_check_success(
|
||||
ss->OpenDatabaseWithFileURL(fileUrl, override, 0, getter_AddRefs(conn)));
|
||||
|
||||
nsCOMPtr<nsIThread> target(get_conn_async_thread(conn));
|
||||
do_check_true(target);
|
||||
PRThread* prThread;
|
||||
target->GetPRThread(&prThread);
|
||||
do_check_true(prThread);
|
||||
nsAutoCString name(PR_GetThreadName(prThread));
|
||||
nsAutoCString expected("sqldb:"_ns);
|
||||
expected.Append(override);
|
||||
do_check_true(StringBeginsWith(name, expected));
|
||||
|
||||
blocking_async_close(conn);
|
||||
}
|
||||
|
||||
TEST(storage_async_thread_naming, AsyncOpenDatabase)
|
||||
{
|
||||
HookSqliteMutex hook;
|
||||
|
||||
nsAutoString filename(u"test_thread_name.sqlite"_ns);
|
||||
nsCOMPtr<nsIFile> dbFile;
|
||||
do_check_success(NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
|
||||
getter_AddRefs(dbFile)));
|
||||
do_check_success(dbFile->Append(filename));
|
||||
nsCOMPtr<mozIStorageService> ss = getService();
|
||||
|
||||
RefPtr<AsyncCompletionSpinner> completionSpinner =
|
||||
new AsyncCompletionSpinner();
|
||||
RefPtr<nsVariant> variant = new nsVariant();
|
||||
variant->SetAsInterface(NS_GET_IID(nsIFile), dbFile);
|
||||
do_check_success(ss->OpenAsyncDatabase(variant, 0, 0, completionSpinner));
|
||||
completionSpinner->SpinUntilCompleted();
|
||||
nsCOMPtr<mozIStorageConnection> conn(
|
||||
do_QueryInterface(completionSpinner->mCompletionValue));
|
||||
nsCOMPtr<nsIThread> target(get_conn_async_thread(conn));
|
||||
do_check_true(target);
|
||||
PRThread* prThread;
|
||||
target->GetPRThread(&prThread);
|
||||
do_check_true(prThread);
|
||||
nsAutoCString name(PR_GetThreadName(prThread));
|
||||
nsAutoCString expected("sqldb:"_ns);
|
||||
expected.Append(NS_ConvertUTF16toUTF8(filename));
|
||||
do_check_true(StringBeginsWith(name, expected));
|
||||
|
||||
blocking_async_close(conn);
|
||||
}
|
||||
|
||||
TEST(storage_async_thread_naming, AsyncClone)
|
||||
{
|
||||
HookSqliteMutex hook;
|
||||
|
||||
nsAutoString filename(u"test_thread_name.sqlite"_ns);
|
||||
nsCOMPtr<nsIFile> dbFile;
|
||||
do_check_success(NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
|
||||
getter_AddRefs(dbFile)));
|
||||
do_check_success(dbFile->Append(filename));
|
||||
nsCOMPtr<mozIStorageService> ss = getService();
|
||||
|
||||
nsCOMPtr<mozIStorageConnection> conn;
|
||||
do_check_success(ss->OpenDatabase(dbFile, 0, getter_AddRefs(conn)));
|
||||
|
||||
RefPtr<AsyncCompletionSpinner> completionSpinner =
|
||||
new AsyncCompletionSpinner();
|
||||
RefPtr<nsVariant> variant = new nsVariant();
|
||||
variant->SetAsInterface(NS_GET_IID(nsIFile), dbFile);
|
||||
do_check_success(conn->AsyncClone(true, completionSpinner));
|
||||
completionSpinner->SpinUntilCompleted();
|
||||
nsCOMPtr<mozIStorageConnection> clone(
|
||||
do_QueryInterface(completionSpinner->mCompletionValue));
|
||||
nsCOMPtr<nsIThread> target(get_conn_async_thread(clone));
|
||||
do_check_true(target);
|
||||
PRThread* prThread;
|
||||
target->GetPRThread(&prThread);
|
||||
do_check_true(prThread);
|
||||
nsAutoCString name(PR_GetThreadName(prThread));
|
||||
nsAutoCString expected("sqldb:"_ns);
|
||||
expected.Append(NS_ConvertUTF16toUTF8(filename));
|
||||
do_check_true(StringBeginsWith(name, expected));
|
||||
|
||||
blocking_async_close(conn);
|
||||
blocking_async_close(clone);
|
||||
}
|
@ -2,6 +2,21 @@
|
||||
* 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/. */
|
||||
|
||||
/**
|
||||
* PRIVACY WARNING
|
||||
* ===============
|
||||
*
|
||||
* Database file names can be exposed through telemetry and in crash reports on
|
||||
* the https://crash-stats.mozilla.org site, to allow recognizing the affected
|
||||
* database.
|
||||
* if your database name may contain privacy sensitive information, e.g. an
|
||||
* URL origin, you should use openDatabaseWithFileURL and pass an explicit
|
||||
* TelemetryFilename to it. That name will be used both for telemetry and for
|
||||
* thread names in crash reports.
|
||||
* If you have different needs (e.g. using the javascript module or an async
|
||||
* connection from the main thread) please coordinate with the mozStorage peers.
|
||||
*/
|
||||
|
||||
import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
|
||||
|
||||
import { setTimeout } from "resource://gre/modules/Timer.sys.mjs";
|
||||
|
Loading…
Reference in New Issue
Block a user