summaryrefslogtreecommitdiffstats
path: root/chrome/common/service_process_util_win.cc
diff options
context:
space:
mode:
authorsanjeevr@chromium.org <sanjeevr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-13 20:27:04 +0000
committersanjeevr@chromium.org <sanjeevr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-13 20:27:04 +0000
commit146354945e1fb1a915ecb009c6732e0e28db9adc (patch)
tree248ec50922622796c7df09720b30c3f4ad6d2fa6 /chrome/common/service_process_util_win.cc
parent6da080717a2ef41e6292090427386d9079e73a59 (diff)
downloadchromium_src-146354945e1fb1a915ecb009c6732e0e28db9adc.zip
chromium_src-146354945e1fb1a915ecb009c6732e0e28db9adc.tar.gz
chromium_src-146354945e1fb1a915ecb009c6732e0e28db9adc.tar.bz2
Spilt code in service_process_utils.cc into separate files for Windows and Posix. Added unit-tests for this file. Also created a ServiceProcessState class that manages global state for the service process.
BUG=None TEST=Unit-tests, cloud print proxy. Review URL: http://codereview.chromium.org/3745001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@62448 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/common/service_process_util_win.cc')
-rw-r--r--chrome/common/service_process_util_win.cc145
1 files changed, 145 insertions, 0 deletions
diff --git a/chrome/common/service_process_util_win.cc b/chrome/common/service_process_util_win.cc
new file mode 100644
index 0000000..6d233e9
--- /dev/null
+++ b/chrome/common/service_process_util_win.cc
@@ -0,0 +1,145 @@
+// Copyright (c) 2010 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/common/service_process_util.h"
+
+#include "base/command_line.h"
+#include "base/file_util.h"
+#include "base/logging.h"
+#include "base/object_watcher.h"
+#include "base/path_service.h"
+#include "base/scoped_handle_win.h"
+#include "base/string16.h"
+#include "base/utf_string_conversions.h"
+#include "base/win_util.h"
+#include "chrome/common/chrome_switches.h"
+
+namespace {
+
+string16 GetServiceProcessReadyEventName() {
+ return UTF8ToWide(
+ GetServiceProcessScopedVersionedName("_service_ready"));
+}
+
+string16 GetServiceProcessShutdownEventName() {
+ return UTF8ToWide(
+ GetServiceProcessScopedVersionedName("_service_shutdown_evt"));
+}
+
+class ServiceProcessShutdownMonitor : public base::ObjectWatcher::Delegate {
+ public:
+ explicit ServiceProcessShutdownMonitor(Task* shutdown_task)
+ : shutdown_task_(shutdown_task) {
+ }
+ void Start() {
+ string16 event_name = GetServiceProcessShutdownEventName();
+ CHECK(event_name.length() <= MAX_PATH);
+ shutdown_event_.Set(CreateEvent(NULL, TRUE, FALSE, event_name.c_str()));
+ watcher_.StartWatching(shutdown_event_.Get(), this);
+ }
+
+ // base::ObjectWatcher::Delegate implementation.
+ virtual void OnObjectSignaled(HANDLE object) {
+ shutdown_task_->Run();
+ shutdown_task_.reset();
+ }
+
+ private:
+ ScopedHandle shutdown_event_;
+ base::ObjectWatcher watcher_;
+ scoped_ptr<Task> shutdown_task_;
+};
+
+} // namespace
+
+bool ForceServiceProcessShutdown(const std::string& version) {
+ ScopedHandle shutdown_event;
+ std::string versioned_name = version;
+ versioned_name.append("_service_shutdown_evt");
+ string16 event_name =
+ UTF8ToWide(GetServiceProcessScopedName(versioned_name));
+ shutdown_event.Set(OpenEvent(EVENT_MODIFY_STATE, FALSE, event_name.c_str()));
+ if (!shutdown_event.IsValid())
+ return false;
+ SetEvent(shutdown_event.Get());
+ return true;
+}
+
+bool CheckServiceProcessReady() {
+ string16 event_name = GetServiceProcessReadyEventName();
+ ScopedHandle event(
+ OpenEvent(SYNCHRONIZE | READ_CONTROL, false, event_name.c_str()));
+ if (!event.IsValid())
+ return false;
+ // Check if the event is signaled.
+ return WaitForSingleObject(event, 0) == WAIT_OBJECT_0;
+}
+
+struct ServiceProcessState::StateData {
+ // An event that is signaled when a service process is ready.
+ ScopedHandle ready_event;
+ scoped_ptr<ServiceProcessShutdownMonitor> shutdown_monitor;
+};
+
+bool ServiceProcessState::TakeSingletonLock() {
+ DCHECK(!state_);
+ string16 event_name = GetServiceProcessReadyEventName();
+ CHECK(event_name.length() <= MAX_PATH);
+ ScopedHandle service_process_ready_event;
+ service_process_ready_event.Set(
+ CreateEvent(NULL, TRUE, FALSE, event_name.c_str()));
+ DWORD error = GetLastError();
+ if ((error == ERROR_ALREADY_EXISTS) || (error == ERROR_ACCESS_DENIED))
+ return false;
+ DCHECK(service_process_ready_event.IsValid());
+ state_ = new StateData;
+ state_->ready_event.Set(service_process_ready_event.Take());
+ return true;
+}
+
+void ServiceProcessState::SignalReady(Task* shutdown_task) {
+ DCHECK(state_);
+ DCHECK(state_->ready_event.IsValid());
+ SetEvent(state_->ready_event.Get());
+ if (shutdown_task) {
+ state_->shutdown_monitor.reset(
+ new ServiceProcessShutdownMonitor(shutdown_task));
+ state_->shutdown_monitor->Start();
+ }
+}
+
+void ServiceProcessState::SignalStopped() {
+ TearDownState();
+ shared_mem_service_data_.reset();
+}
+
+bool ServiceProcessState::AddToAutoRun() {
+ FilePath chrome_path;
+ if (PathService::Get(base::FILE_EXE, &chrome_path)) {
+ CommandLine cmd_line(chrome_path);
+ cmd_line.AppendSwitchASCII(switches::kProcessType,
+ switches::kServiceProcess);
+ // We need a unique name for the command per user-date-dir. Just use the
+ // channel name.
+ return win_util::AddCommandToAutoRun(
+ HKEY_CURRENT_USER,
+ UTF8ToWide(GetAutoRunKey()),
+ cmd_line.command_line_string());
+ }
+ return false;
+}
+
+bool ServiceProcessState::RemoveFromAutoRun() {
+ return win_util::RemoveCommandFromAutoRun(
+ HKEY_CURRENT_USER, UTF8ToWide(GetAutoRunKey()));
+}
+
+void ServiceProcessState::TearDownState() {
+ delete state_;
+ state_ = NULL;
+}
+
+bool ServiceProcessState::ShouldHandleOtherVersion() {
+ return true;
+}