1 // Copyright (c) 2010 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
5 #include "chrome/common/service_process_util_posix.h"
6
7 #include <signal.h>
8 #include <unistd.h>
9
10 #include "base/command_line.h"
11 #include "base/file_util.h"
12 #include "base/logging.h"
13 #include "base/threading/platform_thread.h"
14 #include "chrome/common/auto_start_linux.h"
15 #include "chrome/common/multi_process_lock.h"
16
17 namespace {
18
19 // Attempts to take a lock named |name|. If |waiting| is true then this will
20 // make multiple attempts to acquire the lock.
21 // Caller is responsible for ownership of the MultiProcessLock.
TakeNamedLock(const std::string & name,bool waiting)22 MultiProcessLock* TakeNamedLock(const std::string& name, bool waiting) {
23 scoped_ptr<MultiProcessLock> lock(MultiProcessLock::Create(name));
24 if (lock == NULL) return NULL;
25 bool got_lock = false;
26 for (int i = 0; i < 10; ++i) {
27 if (lock->TryLock()) {
28 got_lock = true;
29 break;
30 }
31 if (!waiting) break;
32 base::PlatformThread::Sleep(100 * i);
33 }
34 if (!got_lock) {
35 lock.reset();
36 }
37 return lock.release();
38 }
39
TakeServiceInitializingLock(bool waiting)40 MultiProcessLock* TakeServiceInitializingLock(bool waiting) {
41 std::string lock_name =
42 GetServiceProcessScopedName("_service_initializing");
43 return TakeNamedLock(lock_name, waiting);
44 }
45
GetBaseDesktopName()46 std::string GetBaseDesktopName() {
47 #if defined(GOOGLE_CHROME_BUILD)
48 return "google-chrome-service.desktop";
49 #else // CHROMIUM_BUILD
50 return "chromium-service.desktop";
51 #endif
52 }
53 } // namespace
54
TakeServiceRunningLock(bool waiting)55 MultiProcessLock* TakeServiceRunningLock(bool waiting) {
56 std::string lock_name =
57 GetServiceProcessScopedName("_service_running");
58 return TakeNamedLock(lock_name, waiting);
59 }
60
ForceServiceProcessShutdown(const std::string & version,base::ProcessId process_id)61 bool ForceServiceProcessShutdown(const std::string& version,
62 base::ProcessId process_id) {
63 if (kill(process_id, SIGTERM) < 0) {
64 PLOG(ERROR) << "kill";
65 return false;
66 }
67 return true;
68 }
69
CheckServiceProcessReady()70 bool CheckServiceProcessReady() {
71 scoped_ptr<MultiProcessLock> running_lock(TakeServiceRunningLock(false));
72 return running_lock.get() == NULL;
73 }
74
TakeSingletonLock()75 bool ServiceProcessState::TakeSingletonLock() {
76 state_->initializing_lock_.reset(TakeServiceInitializingLock(true));
77 return state_->initializing_lock_.get();
78 }
79
AddToAutoRun()80 bool ServiceProcessState::AddToAutoRun() {
81 DCHECK(autorun_command_line_.get());
82 #if defined(GOOGLE_CHROME_BUILD)
83 std::string app_name = "Google Chrome Service";
84 #else // CHROMIUM_BUILD
85 std::string app_name = "Chromium Service";
86 #endif
87 return AutoStart::AddApplication(
88 GetServiceProcessScopedName(GetBaseDesktopName()),
89 app_name,
90 autorun_command_line_->command_line_string(),
91 false);
92 }
93
RemoveFromAutoRun()94 bool ServiceProcessState::RemoveFromAutoRun() {
95 return AutoStart::Remove(
96 GetServiceProcessScopedName(GetBaseDesktopName()));
97 }
98