summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorevan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-18 22:04:28 +0000
committerevan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-18 22:04:28 +0000
commit19d7e9684e85feae1ecf9959baf07a94b01b1bce (patch)
treebd30e91dc44ae37bad8670b88eaca77ece65699a /chrome
parent3851091de6451d26ba85318a9c36bd7f2923d2d8 (diff)
downloadchromium_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.scons1
-rw-r--r--chrome/browser/browser_main.cc2
-rw-r--r--chrome/browser/process_singleton.h34
-rw-r--r--chrome/browser/process_singleton_linux.cc71
-rw-r--r--chrome/common/temp_scaffolding_stubs.h7
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: