1// Copyright (c) 2011 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/multi_process_lock.h"
6
7#include "base/logging.h"
8#include "base/mac/scoped_cftyperef.h"
9#include "base/strings/sys_string_conversions.h"
10
11#include <servers/bootstrap.h>
12
13class MultiProcessLockMac : public MultiProcessLock {
14 public:
15  explicit MultiProcessLockMac(const std::string& name) : name_(name) { }
16
17  virtual ~MultiProcessLockMac() {
18    if (port_ != NULL) {
19      Unlock();
20    }
21  }
22
23  virtual bool TryLock() OVERRIDE {
24    if (port_ != NULL) {
25      DLOG(ERROR) << "MultiProcessLock is already locked - " << name_;
26      return true;
27    }
28
29    if (name_.length() >= BOOTSTRAP_MAX_NAME_LEN) {
30      LOG(ERROR) << "Socket name too long (" << name_.length()
31                 << " >= " << BOOTSTRAP_MAX_NAME_LEN << ") - " << name_;
32      return false;
33    }
34
35    CFStringRef cf_name(base::SysUTF8ToCFStringRef(name_));
36    base::ScopedCFTypeRef<CFStringRef> scoped_cf_name(cf_name);
37    port_.reset(CFMessagePortCreateLocal(NULL, cf_name, NULL, NULL, NULL));
38    return port_ != NULL;
39  }
40
41  virtual void Unlock() OVERRIDE {
42    if (port_ == NULL) {
43      DLOG(ERROR) << "Over-unlocked MultiProcessLock - " << name_;
44      return;
45    }
46    port_.reset();
47  }
48
49 private:
50  std::string name_;
51  base::ScopedCFTypeRef<CFMessagePortRef> port_;
52  DISALLOW_COPY_AND_ASSIGN(MultiProcessLockMac);
53};
54
55MultiProcessLock* MultiProcessLock::Create(const std::string &name) {
56  return new MultiProcessLockMac(name);
57}
58