diff options
author | evan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-18 22:04:28 +0000 |
---|---|---|
committer | evan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-18 22:04:28 +0000 |
commit | 19d7e9684e85feae1ecf9959baf07a94b01b1bce (patch) | |
tree | bd30e91dc44ae37bad8670b88eaca77ece65699a /chrome | |
parent | 3851091de6451d26ba85318a9c36bd7f2923d2d8 (diff) | |
download | chromium_src-19d7e9684e85feae1ecf9959baf07a94b01b1bce.zip chromium_src-19d7e9684e85feae1ecf9959baf07a94b01b1bce.tar.gz chromium_src-19d7e9684e85feae1ecf9959baf07a94b01b1bce.tar.bz2 |
Implement skeletal ProcessSingleton on Linux to cut down on NOTIMPLEMENTED()s.
We now will refuse to run a second browser process if one is already running;
making the second invocation bring up new windows in the first remains left to
be implemented.
Review URL: http://codereview.chromium.org/20448
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@9980 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/browser.scons | 1 | ||||
-rw-r--r-- | chrome/browser/browser_main.cc | 2 | ||||
-rw-r--r-- | chrome/browser/process_singleton.h | 34 | ||||
-rw-r--r-- | chrome/browser/process_singleton_linux.cc | 71 | ||||
-rw-r--r-- | chrome/common/temp_scaffolding_stubs.h | 7 |
5 files changed, 100 insertions, 15 deletions
diff --git a/chrome/browser/browser.scons b/chrome/browser/browser.scons index faeb393..553853a 100644 --- a/chrome/browser/browser.scons +++ b/chrome/browser/browser.scons @@ -785,6 +785,7 @@ if not env.Bit('windows'): if env.Bit('linux'): input_files.Extend([ 'browser_main_gtk.cc', + 'process_singleton_linux.cc', 'gtk/browser_toolbar_view_gtk.cc', 'gtk/browser_window_factory_gtk.cc', 'gtk/browser_window_gtk.cc', diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc index e7cd0a1..caaa963 100644 --- a/chrome/browser/browser_main.cc +++ b/chrome/browser/browser_main.cc @@ -69,7 +69,6 @@ #include "chrome/browser/extensions/extension_protocols.h" #include "chrome/browser/jankometer.h" #include "chrome/browser/metrics/user_metrics.h" -#include "chrome/browser/process_singleton.h" #include "chrome/browser/net/dns_global.h" #include "chrome/browser/net/sdch_dictionary_fetcher.h" #include "chrome/browser/net/url_fixer_upper.h" @@ -99,6 +98,7 @@ #if !defined(OS_MACOSX) #include "net_resources.h" +#include "chrome/browser/process_singleton.h" #endif namespace Platform { diff --git a/chrome/browser/process_singleton.h b/chrome/browser/process_singleton.h index 7e38def..4f514c4 100644 --- a/chrome/browser/process_singleton.h +++ b/chrome/browser/process_singleton.h @@ -5,8 +5,11 @@ #ifndef CHROME_BROWSER_PROCESS_SINGLETON_H_ #define CHROME_BROWSER_PROCESS_SINGLETON_H_ -#include <string> +#include "build/build_config.h" + +#if defined(OS_WIN) #include <windows.h> +#endif #include "base/basictypes.h" #include "base/file_path.h" @@ -18,8 +21,9 @@ // we can be sure that no more than one copy of the application can be // running at once with a given data directory. // -// The Windows implementation uses an invisible global message window for -// IPC. +// Implementation notes: +// - the Windows implementation uses an invisible global message window; +// - the Linux implementation uses a Unix domain socket in ~/.chromium. class ProcessSingleton { public: @@ -27,14 +31,15 @@ class ProcessSingleton { ~ProcessSingleton(); // Returns true if another process was found and notified, false if we - // should continue with this process. Roughly based on Mozilla + // should continue with this process. + // Windows code roughly based on Mozilla. // // TODO(brettw): this will not handle all cases. If two process start up too - // close to each other, the window might not have been created yet for the + // close to each other, the Create() might not yet have happened for the // first one, so this function won't find it. bool NotifyOtherProcess(); - // Create the toplevel message window for IPC. + // Set ourselves up as the singleton instance. void Create(); // Blocks the dispatch of CopyData messages. @@ -47,13 +52,16 @@ class ProcessSingleton { locked_ = false; } - // This ugly behemoth handles startup commands sent from another process. - LRESULT OnCopyData(HWND hwnd, const COPYDATASTRUCT* cds); - // Looks for zombie renderer and plugin processes that could have survived. void HuntForZombieChromeProcesses(); private: + bool locked_; + +#if defined(OS_WIN) + // This ugly behemoth handles startup commands sent from another process. + LRESULT OnCopyData(HWND hwnd, const COPYDATASTRUCT* cds); + LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, @@ -70,7 +78,13 @@ class ProcessSingleton { HWND remote_window_; // The HWND_MESSAGE of another browser. HWND window_; // The HWND_MESSAGE window. - bool locked_; +#elif defined(OS_LINUX) + // Set up a socket and sockaddr appropriate for messaging. + void SetupSocket(int* sock, struct sockaddr_un* addr); + + // Path in file system to the socket. + FilePath socket_path_; +#endif DISALLOW_COPY_AND_ASSIGN(ProcessSingleton); }; diff --git a/chrome/browser/process_singleton_linux.cc b/chrome/browser/process_singleton_linux.cc new file mode 100644 index 0000000..4ca8f17 --- /dev/null +++ b/chrome/browser/process_singleton_linux.cc @@ -0,0 +1,71 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/process_singleton.h" + +#include <errno.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> + +#include "base/logging.h" +#include "base/string_util.h" + +ProcessSingleton::ProcessSingleton(const FilePath& user_data_dir) { + socket_path_ = user_data_dir.Append("Singleton Socket"); +} + +ProcessSingleton::~ProcessSingleton() { +} + +bool ProcessSingleton::NotifyOtherProcess() { + int sock; + sockaddr_un addr; + SetupSocket(&sock, &addr); + + if (connect(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0 && + (errno == ENOENT || errno == ECONNREFUSED)) { + return false; // Tell the caller there's nobody to notify. + } + + // TODO(port): pass in info to the other process. + NOTIMPLEMENTED() << " don't know how to notify other process about us."; + + return true; // We did our best, so we die here. +} + +void ProcessSingleton::Create() { + int sock; + sockaddr_un addr; + SetupSocket(&sock, &addr); + + if (unlink(socket_path_.value().c_str()) < 0) + DCHECK_EQ(errno, ENOENT); + + if (bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0) + LOG(ERROR) << "bind() failed: " << strerror(errno); + + if (listen(sock, 5) < 0) + NOTREACHED() << "listen failed: " << strerror(errno); + + // TODO(port): register this socket as something we care about getting + // input on, process messages, etc. + NOTIMPLEMENTED() << " need to listen on the singleton socket."; +} + +void ProcessSingleton::HuntForZombieChromeProcesses() { + // On Windows, this examines all the chrome.exe processes to see if one + // is hung. TODO(port): should we do anything here? + NOTIMPLEMENTED(); +} + +void ProcessSingleton::SetupSocket(int* sock, struct sockaddr_un* addr) { + *sock = socket(PF_UNIX, SOCK_STREAM, 0); + if (*sock < 0) + LOG(FATAL) << "socket() failed: " << strerror(errno); + + addr->sun_family = AF_UNIX; + base::strlcpy(addr->sun_path, socket_path_.value().c_str(), + sizeof(addr->sun_path)); +} diff --git a/chrome/common/temp_scaffolding_stubs.h b/chrome/common/temp_scaffolding_stubs.h index 3c7f710..2e487ac 100644 --- a/chrome/common/temp_scaffolding_stubs.h +++ b/chrome/common/temp_scaffolding_stubs.h @@ -109,10 +109,8 @@ class X509Certificate; //--------------------------------------------------------------------------- // These stubs are for Browser_main() -// TODO(port): the current ProcessSingleton implementation is very -// windows-specific, but provides the concept of a singleton browser -// process per user-data-dir. Investigate how achieve this on other -// platforms and see if this API works. +#if defined(OS_MACOSX) +// TODO(port): needs an implementation of ProcessSingleton. class ProcessSingleton { public: explicit ProcessSingleton(const FilePath& user_data_dir) { } @@ -126,6 +124,7 @@ class ProcessSingleton { void Lock() { NOTIMPLEMENTED(); } void Unlock() { NOTIMPLEMENTED(); } }; +#endif // defined(OS_MACOSX) class GoogleUpdateSettings { public: |