blob: c6233fc92a82544724dc669a0d175aebd1dadd38 [file] [log] [blame]
[email protected]fc14cef2009-01-27 22:17:291// Copyright (c) 2009 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]7c47ae3e2009-02-18 00:34:215#ifndef CHROME_BROWSER_PROCESS_SINGLETON_H_
6#define CHROME_BROWSER_PROCESS_SINGLETON_H_
[email protected]32b76ef2010-07-26 23:08:247#pragma once
[email protected]fc14cef2009-01-27 22:17:298
[email protected]19d7e9682009-02-18 22:04:289#include "build/build_config.h"
10
11#if defined(OS_WIN)
[email protected]fc14cef2009-01-27 22:17:2912#include <windows.h>
[email protected]19d7e9682009-02-18 22:04:2813#endif
[email protected]fc14cef2009-01-27 22:17:2914
[email protected]fc14cef2009-01-27 22:17:2915#include "base/basictypes.h"
[email protected]f7011fcb2009-01-28 21:54:3216#include "base/file_path.h"
[email protected]b674dc732009-05-20 20:41:0017#include "base/logging.h"
18#include "base/non_thread_safe.h"
19#include "base/ref_counted.h"
[email protected]5c7293a2010-03-17 06:40:5720#include "gfx/native_widget_types.h"
[email protected]fc14cef2009-01-27 22:17:2921
[email protected]0189bbd2009-10-12 22:50:3922class CommandLine;
23
[email protected]7c47ae3e2009-02-18 00:34:2124// ProcessSingleton ----------------------------------------------------------
[email protected]fc14cef2009-01-27 22:17:2925//
[email protected]7c47ae3e2009-02-18 00:34:2126// This class allows different browser processes to communicate with
27// each other. It is named according to the user data directory, so
28// we can be sure that no more than one copy of the application can be
29// running at once with a given data directory.
30//
[email protected]19d7e9682009-02-18 22:04:2831// Implementation notes:
32// - the Windows implementation uses an invisible global message window;
[email protected]e134a722009-02-23 23:54:0233// - the Linux implementation uses a Unix domain socket in the user data dir.
[email protected]fc14cef2009-01-27 22:17:2934
[email protected]b674dc732009-05-20 20:41:0035class ProcessSingleton : public NonThreadSafe {
[email protected]fc14cef2009-01-27 22:17:2936 public:
[email protected]9f20a6d02009-08-21 01:18:3737 enum NotifyResult {
38 PROCESS_NONE,
39 PROCESS_NOTIFIED,
40 PROFILE_IN_USE,
[email protected]4a44bc32010-05-28 22:22:4441 LOCK_ERROR,
[email protected]9f20a6d02009-08-21 01:18:3742 };
43
[email protected]7c47ae3e2009-02-18 00:34:2144 explicit ProcessSingleton(const FilePath& user_data_dir);
45 ~ProcessSingleton();
[email protected]fc14cef2009-01-27 22:17:2946
[email protected]c0d297952009-09-17 21:00:1847 // Notify another process, if available.
[email protected]fc14cef2009-01-27 22:17:2948 // Returns true if another process was found and notified, false if we
[email protected]19d7e9682009-02-18 22:04:2849 // should continue with this process.
50 // Windows code roughly based on Mozilla.
[email protected]fc14cef2009-01-27 22:17:2951 //
52 // TODO(brettw): this will not handle all cases. If two process start up too
[email protected]19d7e9682009-02-18 22:04:2853 // close to each other, the Create() might not yet have happened for the
[email protected]fc14cef2009-01-27 22:17:2954 // first one, so this function won't find it.
[email protected]9f20a6d02009-08-21 01:18:3755 NotifyResult NotifyOtherProcess();
[email protected]fc14cef2009-01-27 22:17:2956
[email protected]4a44bc32010-05-28 22:22:4457 // Notify another process, if available. Otherwise sets ourselves as the
58 // singleton instance. Returns PROCESS_NONE if we became the singleton
59 // instance.
60 NotifyResult NotifyOtherProcessOrCreate();
61
[email protected]753efc42010-03-09 19:52:1662#if defined(OS_POSIX) && !defined(OS_MACOSX)
[email protected]c0d297952009-09-17 21:00:1863 // Exposed for testing. We use a timeout on Linux, and in tests we want
64 // this timeout to be short.
[email protected]0189bbd2009-10-12 22:50:3965 NotifyResult NotifyOtherProcessWithTimeout(const CommandLine& command_line,
[email protected]4a44bc32010-05-28 22:22:4466 int timeout_seconds,
67 bool kill_unresponsive);
68 NotifyResult NotifyOtherProcessWithTimeoutOrCreate(
69 const CommandLine& command_line,
70 int timeout_seconds);
[email protected]c0d297952009-09-17 21:00:1871#endif
72
[email protected]4dd42242010-04-07 02:21:1573 // Sets ourself up as the singleton instance. Returns true on success. If
74 // false is returned, we are not the singleton instance and the caller must
75 // exit.
76 bool Create();
[email protected]fc14cef2009-01-27 22:17:2977
[email protected]9f20a6d02009-08-21 01:18:3778 // Clear any lock state during shutdown.
79 void Cleanup();
80
[email protected]175a7a22009-05-03 15:57:5381 // Blocks the dispatch of CopyData messages. foreground_window refers
82 // to the window that should be set to the foreground if a CopyData message
83 // is received while the ProcessSingleton is locked.
84 void Lock(gfx::NativeWindow foreground_window) {
[email protected]b674dc732009-05-20 20:41:0085 DCHECK(CalledOnValidThread());
[email protected]fc14cef2009-01-27 22:17:2986 locked_ = true;
[email protected]175a7a22009-05-03 15:57:5387 foreground_window_ = foreground_window;
[email protected]fc14cef2009-01-27 22:17:2988 }
89
90 // Allows the dispatch of CopyData messages.
91 void Unlock() {
[email protected]b674dc732009-05-20 20:41:0092 DCHECK(CalledOnValidThread());
[email protected]fc14cef2009-01-27 22:17:2993 locked_ = false;
[email protected]175a7a22009-05-03 15:57:5394 foreground_window_ = NULL;
[email protected]fc14cef2009-01-27 22:17:2995 }
96
[email protected]b674dc732009-05-20 20:41:0097 bool locked() {
98 DCHECK(CalledOnValidThread());
99 return locked_;
100 }
101
[email protected]fc14cef2009-01-27 22:17:29102 private:
[email protected]753efc42010-03-09 19:52:16103#if !defined(OS_MACOSX)
[email protected]8b08cbd2009-08-04 05:34:19104 // Timeout for the current browser process to respond. 20 seconds should be
105 // enough. It's only used in Windows and Linux implementations.
106 static const int kTimeoutInSeconds = 20;
107#endif
108
[email protected]19d7e9682009-02-18 22:04:28109 bool locked_;
[email protected]175a7a22009-05-03 15:57:53110 gfx::NativeWindow foreground_window_;
[email protected]19d7e9682009-02-18 22:04:28111
112#if defined(OS_WIN)
113 // This ugly behemoth handles startup commands sent from another process.
114 LRESULT OnCopyData(HWND hwnd, const COPYDATASTRUCT* cds);
115
[email protected]fc14cef2009-01-27 22:17:29116 LRESULT CALLBACK WndProc(HWND hwnd,
117 UINT message,
118 WPARAM wparam,
119 LPARAM lparam);
120
121 static LRESULT CALLBACK WndProcStatic(HWND hwnd,
122 UINT message,
123 WPARAM wparam,
124 LPARAM lparam) {
[email protected]7c47ae3e2009-02-18 00:34:21125 ProcessSingleton* msg_wnd = reinterpret_cast<ProcessSingleton*>(
[email protected]fc14cef2009-01-27 22:17:29126 GetWindowLongPtr(hwnd, GWLP_USERDATA));
127 return msg_wnd->WndProc(hwnd, message, wparam, lparam);
128 }
129
130 HWND remote_window_; // The HWND_MESSAGE of another browser.
131 HWND window_; // The HWND_MESSAGE window.
[email protected]753efc42010-03-09 19:52:16132#elif !defined(OS_MACOSX)
[email protected]19d7e9682009-02-18 22:04:28133 // Path in file system to the socket.
134 FilePath socket_path_;
[email protected]b674dc732009-05-20 20:41:00135
[email protected]9f20a6d02009-08-21 01:18:37136 // Path in file system to the lock.
137 FilePath lock_path_;
138
[email protected]b674dc732009-05-20 20:41:00139 // Helper class for linux specific messages. LinuxWatcher is ref counted
140 // because it posts messages between threads.
141 class LinuxWatcher;
142 scoped_refptr<LinuxWatcher> watcher_;
[email protected]19d7e9682009-02-18 22:04:28143#endif
[email protected]fc14cef2009-01-27 22:17:29144
[email protected]7c47ae3e2009-02-18 00:34:21145 DISALLOW_COPY_AND_ASSIGN(ProcessSingleton);
[email protected]fc14cef2009-01-27 22:17:29146};
147
[email protected]175a7a22009-05-03 15:57:53148#endif // CHROME_BROWSER_PROCESS_SINGLETON_H_