14a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved.
24a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
34a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// found in the LICENSE file.
44a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
54a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/common/multi_process_lock.h"
64a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
74a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "base/logging.h"
84a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "base/mac/scoped_cftyperef.h"
94a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "base/sys_string_conversions.h"
104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochclass MultiProcessLockMac : public MultiProcessLock {
124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch public:
134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  explicit MultiProcessLockMac(const std::string& name) : name_(name) { }
144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
154a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  virtual ~MultiProcessLockMac() {
164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    if (port_ != NULL) {
174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      Unlock();
184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    }
194a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  virtual bool TryLock() {
224a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    if (port_ != NULL) {
234a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      DLOG(ERROR) << "MultiProcessLock is already locked - " << name_;
244a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      return true;
254a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    }
264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    if (name_.length() > MULTI_PROCESS_LOCK_NAME_MAX_LEN) {
28201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      LOG(ERROR) << "Socket name too long (" << name_.length()
29201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                 << " > " << MULTI_PROCESS_LOCK_NAME_MAX_LEN << ") - " << name_;
304a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      return false;
314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    }
324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
334a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    CFStringRef cf_name(base::SysUTF8ToCFStringRef(name_));
344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    base::mac::ScopedCFTypeRef<CFStringRef> scoped_cf_name(cf_name);
354a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    port_.reset(CFMessagePortCreateLocal(NULL, cf_name, NULL, NULL, NULL));
364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    return port_ != NULL;
374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
384a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
394a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  virtual void Unlock() {
404a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    if (port_ == NULL) {
414a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      DLOG(ERROR) << "Over-unlocked MultiProcessLock - " << name_;
424a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      return;
434a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    }
444a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    port_.reset();
454a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
464a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
474a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch private:
484a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  std::string name_;
494a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  base::mac::ScopedCFTypeRef<CFMessagePortRef> port_;
504a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(MultiProcessLockMac);
514a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch};
524a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben MurdochMultiProcessLock* MultiProcessLock::Create(const std::string &name) {
544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  return new MultiProcessLockMac(name);
554a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
56