Singleton must be created on request

The creation of singleton relies on the `userData` dir, which can be
changed by user, we have to ensure singleton uses the `userData` dir set
by user.
This commit is contained in:
Cheng Zhao 2018-01-03 18:59:12 +09:00
parent 0cce6b3d21
commit 952928dc79
7 changed files with 41 additions and 46 deletions

View file

@ -565,6 +565,11 @@ void App::OnWindowAllClosed() {
void App::OnQuit() { void App::OnQuit() {
int exitCode = AtomBrowserMainParts::Get()->GetExitCode(); int exitCode = AtomBrowserMainParts::Get()->GetExitCode();
Emit("quit", exitCode); Emit("quit", exitCode);
if (process_singleton_) {
process_singleton_->Cleanup();
process_singleton_.reset();
}
} }
void App::OnOpenFile(bool* prevent_default, const std::string& file_path) { void App::OnOpenFile(bool* prevent_default, const std::string& file_path) {
@ -592,12 +597,15 @@ void App::OnFinishLaunching(const base::DictionaryValue& launch_info) {
Emit("ready", launch_info); Emit("ready", launch_info);
} }
void App::OnAccessibilitySupportChanged() {
Emit("accessibility-support-changed", IsAccessibilitySupportEnabled());
}
void App::OnPreMainMessageLoopRun() { void App::OnPreMainMessageLoopRun() {
content::BrowserChildProcessObserver::Add(this); content::BrowserChildProcessObserver::Add(this);
if (process_singleton_) {
process_singleton_->OnBrowserReady();
}
}
void App::OnAccessibilitySupportChanged() {
Emit("accessibility-support-changed", IsAccessibilitySupportEnabled());
} }
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
@ -848,18 +856,19 @@ std::string App::GetLocale() {
bool App::MakeSingleInstance( bool App::MakeSingleInstance(
const ProcessSingleton::NotificationCallback& callback) { const ProcessSingleton::NotificationCallback& callback) {
auto process_singleton = AtomBrowserMainParts::Get()->process_singleton(); if (process_singleton_)
if (process_singleton_created_)
return false; return false;
process_singleton->RegisterSingletonNotificationCallback( base::FilePath user_dir;
base::Bind(NotificationCallbackWrapper, callback)); PathService::Get(brightray::DIR_USER_DATA, &user_dir);
process_singleton_.reset(new ProcessSingleton(
user_dir, base::Bind(NotificationCallbackWrapper, callback)));
switch (process_singleton->NotifyOtherProcessOrCreate()) { switch (process_singleton_->NotifyOtherProcessOrCreate()) {
case ProcessSingleton::NotifyResult::LOCK_ERROR: case ProcessSingleton::NotifyResult::LOCK_ERROR:
case ProcessSingleton::NotifyResult::PROFILE_IN_USE: case ProcessSingleton::NotifyResult::PROFILE_IN_USE:
case ProcessSingleton::NotifyResult::PROCESS_NOTIFIED: { case ProcessSingleton::NotifyResult::PROCESS_NOTIFIED: {
process_singleton_created_ = true; process_singleton_.reset();
return true; return true;
} }
case ProcessSingleton::NotifyResult::PROCESS_NONE: case ProcessSingleton::NotifyResult::PROCESS_NONE:
@ -869,9 +878,9 @@ bool App::MakeSingleInstance(
} }
void App::ReleaseSingleInstance() { void App::ReleaseSingleInstance() {
auto process_singleton = AtomBrowserMainParts::Get()->process_singleton(); if (process_singleton_) {
if (process_singleton) { process_singleton_->Cleanup();
process_singleton->Cleanup(); process_singleton_.reset();
} }
} }

View file

@ -218,6 +218,8 @@ class App : public AtomBrowserClient::Delegate,
JumpListResult SetJumpList(v8::Local<v8::Value> val, mate::Arguments* args); JumpListResult SetJumpList(v8::Local<v8::Value> val, mate::Arguments* args);
#endif // defined(OS_WIN) #endif // defined(OS_WIN)
std::unique_ptr<ProcessSingleton> process_singleton_;
#if defined(USE_NSS_CERTS) #if defined(USE_NSS_CERTS)
std::unique_ptr<CertificateManagerModel> certificate_manager_model_; std::unique_ptr<CertificateManagerModel> certificate_manager_model_;
#endif #endif
@ -232,8 +234,6 @@ class App : public AtomBrowserClient::Delegate,
std::unique_ptr<atom::ProcessMetric>>; std::unique_ptr<atom::ProcessMetric>>;
ProcessMetricMap app_metrics_; ProcessMetricMap app_metrics_;
bool process_singleton_created_ = false;
DISALLOW_COPY_AND_ASSIGN(App); DISALLOW_COPY_AND_ASSIGN(App);
}; };

View file

@ -128,10 +128,6 @@ void AtomBrowserMainParts::PostEarlyInitialization() {
bridge_task_runner_ = new BridgeTaskRunner; bridge_task_runner_ = new BridgeTaskRunner;
base::ThreadTaskRunnerHandle handle(bridge_task_runner_); base::ThreadTaskRunnerHandle handle(bridge_task_runner_);
base::FilePath user_dir;
PathService::Get(brightray::DIR_USER_DATA, &user_dir);
process_singleton_.reset(new ProcessSingleton(user_dir));
// The ProxyResolverV8 has setup a complete V8 environment, in order to // The ProxyResolverV8 has setup a complete V8 environment, in order to
// avoid conflicts we only initialize our V8 environment after that. // avoid conflicts we only initialize our V8 environment after that.
js_env_.reset(new JavascriptEnvironment); js_env_.reset(new JavascriptEnvironment);
@ -188,9 +184,6 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() {
bridge_task_runner_->MessageLoopIsReady(); bridge_task_runner_->MessageLoopIsReady();
bridge_task_runner_ = nullptr; bridge_task_runner_ = nullptr;
// Notify observers that main thread message loop was initialized.
Browser::Get()->PreMainMessageLoopRun();
#if defined(USE_X11) #if defined(USE_X11)
libgtkui::GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess()); libgtkui::GtkInitFromCommandLine(*base::CommandLine::ForCurrentProcess());
#endif #endif
@ -202,8 +195,8 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() {
Browser::Get()->DidFinishLaunching(*empty_info); Browser::Get()->DidFinishLaunching(*empty_info);
#endif #endif
if (process_singleton_) // Notify observers that main thread message loop was initialized.
process_singleton_->OnBrowserReady(); Browser::Get()->PreMainMessageLoopRun();
} }
bool AtomBrowserMainParts::MainMessageLoopRun(int* result_code) { bool AtomBrowserMainParts::MainMessageLoopRun(int* result_code) {
@ -241,12 +234,4 @@ void AtomBrowserMainParts::PostMainMessageLoopRun() {
} }
} }
void AtomBrowserMainParts::PostDestroyThreads() {
brightray::BrowserMainParts::PostDestroyThreads();
if (process_singleton_) {
process_singleton_->Cleanup();
process_singleton_.reset();
}
}
} // namespace atom } // namespace atom

View file

@ -11,7 +11,6 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "brightray/browser/browser_main_parts.h" #include "brightray/browser/browser_main_parts.h"
#include "chrome/browser/process_singleton.h"
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
class BrowserProcess; class BrowserProcess;
@ -45,7 +44,6 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
base::Closure RegisterDestructionCallback(const base::Closure& callback); base::Closure RegisterDestructionCallback(const base::Closure& callback);
Browser* browser() { return browser_.get(); } Browser* browser() { return browser_.get(); }
ProcessSingleton* process_singleton() { return process_singleton_.get(); }
protected: protected:
// content::BrowserMainParts: // content::BrowserMainParts:
@ -59,7 +57,6 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
void PreMainMessageLoopStart() override; void PreMainMessageLoopStart() override;
#endif #endif
void PostDestroyThreads() override;
private: private:
#if defined(OS_POSIX) #if defined(OS_POSIX)
@ -88,7 +85,6 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts {
std::unique_ptr<AtomBindings> atom_bindings_; std::unique_ptr<AtomBindings> atom_bindings_;
std::unique_ptr<NodeEnvironment> node_env_; std::unique_ptr<NodeEnvironment> node_env_;
std::unique_ptr<NodeDebugger> node_debugger_; std::unique_ptr<NodeDebugger> node_debugger_;
std::unique_ptr<ProcessSingleton> process_singleton_;
base::Timer gc_timer_; base::Timer gc_timer_;

View file

@ -62,7 +62,8 @@ class ProcessSingleton {
base::Callback<bool(const base::CommandLine::StringVector& command_line, base::Callback<bool(const base::CommandLine::StringVector& command_line,
const base::FilePath& current_directory)>; const base::FilePath& current_directory)>;
explicit ProcessSingleton(const base::FilePath& user_data_dir); ProcessSingleton(const base::FilePath& user_data_dir,
const NotificationCallback& notification_callback);
~ProcessSingleton(); ~ProcessSingleton();
// Notify another process, if available. Otherwise sets ourselves as the // Notify another process, if available. Otherwise sets ourselves as the
@ -98,11 +99,6 @@ class ProcessSingleton {
const ShouldKillRemoteProcessCallback& display_dialog_callback); const ShouldKillRemoteProcessCallback& display_dialog_callback);
#endif #endif
void RegisterSingletonNotificationCallback(
const NotificationCallback& callback) {
notification_callback_ = callback;
}
protected: protected:
// Notify another process, if available. // Notify another process, if available.
// Returns true if another process was found and notified, false if we should // Returns true if another process was found and notified, false if we should

View file

@ -85,6 +85,7 @@
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/threading/platform_thread.h" #include "base/threading/platform_thread.h"
#include "base/threading/thread_restrictions.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
@ -716,9 +717,13 @@ void ProcessSingleton::LinuxWatcher::SocketReader::FinishWithACK(
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// ProcessSingleton // ProcessSingleton
// //
ProcessSingleton::ProcessSingleton(const base::FilePath& user_data_dir) ProcessSingleton::ProcessSingleton(
: current_pid_(base::GetCurrentProcId()) { const base::FilePath& user_data_dir,
const NotificationCallback& notification_callback)
: notification_callback_(notification_callback),
current_pid_(base::GetCurrentProcId()) {
// The user_data_dir may have not been created yet. // The user_data_dir may have not been created yet.
base::ThreadRestrictions::ScopedAllowIO allow_io;
base::CreateDirectoryAndGetError(user_data_dir, nullptr); base::CreateDirectoryAndGetError(user_data_dir, nullptr);
socket_path_ = user_data_dir.Append(kSingletonSocketFilename); socket_path_ = user_data_dir.Append(kSingletonSocketFilename);
@ -957,6 +962,7 @@ void ProcessSingleton::DisablePromptForTesting() {
} }
bool ProcessSingleton::Create() { bool ProcessSingleton::Create() {
base::ThreadRestrictions::ScopedAllowIO allow_io;
int sock; int sock;
sockaddr_un addr; sockaddr_un addr;

View file

@ -182,8 +182,11 @@ bool TerminateAppWithError() {
} // namespace } // namespace
ProcessSingleton::ProcessSingleton(const base::FilePath& user_data_dir) ProcessSingleton::ProcessSingleton(
: is_virtualized_(false), const base::FilePath& user_data_dir,
const NotificationCallback& notification_callback)
: notification_callback_(notification_callback),
is_virtualized_(false),
lock_file_(INVALID_HANDLE_VALUE), lock_file_(INVALID_HANDLE_VALUE),
user_data_dir_(user_data_dir), user_data_dir_(user_data_dir),
should_kill_remote_process_callback_(base::Bind(&TerminateAppWithError)) { should_kill_remote_process_callback_(base::Bind(&TerminateAppWithError)) {