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
17namespace {
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.
22MultiProcessLock* 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
40MultiProcessLock* TakeServiceInitializingLock(bool waiting) {
41  std::string lock_name =
42      GetServiceProcessScopedName("_service_initializing");
43  return TakeNamedLock(lock_name, waiting);
44}
45
46std::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
55MultiProcessLock* TakeServiceRunningLock(bool waiting) {
56  std::string lock_name =
57      GetServiceProcessScopedName("_service_running");
58  return TakeNamedLock(lock_name, waiting);
59}
60
61bool 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
70bool CheckServiceProcessReady() {
71  scoped_ptr<MultiProcessLock> running_lock(TakeServiceRunningLock(false));
72  return running_lock.get() == NULL;
73}
74
75bool ServiceProcessState::TakeSingletonLock() {
76  state_->initializing_lock_.reset(TakeServiceInitializingLock(true));
77  return state_->initializing_lock_.get();
78}
79
80bool 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
94bool ServiceProcessState::RemoveFromAutoRun() {
95  return AutoStart::Remove(
96      GetServiceProcessScopedName(GetBaseDesktopName()));
97}
98