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/strings/utf_string_conversions.h"
9#include "base/win/scoped_handle.h"
10
11class MultiProcessLockWin : public MultiProcessLock {
12 public:
13  explicit MultiProcessLockWin(const std::string& name) : name_(name) { }
14
15  virtual ~MultiProcessLockWin() {
16    if (event_.Get() != NULL) {
17      Unlock();
18    }
19  }
20
21  virtual bool TryLock() {
22    if (event_.Get() != NULL) {
23      DLOG(ERROR) << "MultiProcessLock is already locked - " << name_;
24      return true;
25    }
26
27    if (name_.length() >= MAX_PATH) {
28      LOG(ERROR) << "Socket name too long (" << name_.length()
29                 << " >= " << MAX_PATH << ") - " << name_;
30      return false;
31    }
32
33    base::string16 wname = base::UTF8ToUTF16(name_);
34    event_.Set(CreateEvent(NULL, FALSE, FALSE, wname.c_str()));
35    if (event_.Get() && GetLastError() != ERROR_ALREADY_EXISTS) {
36      return true;
37    } else {
38      event_.Set(NULL);
39      return false;
40    }
41  }
42
43  virtual void Unlock() {
44    if (event_.Get() == NULL) {
45      DLOG(ERROR) << "Over-unlocked MultiProcessLock - " << name_;
46      return;
47    }
48    event_.Set(NULL);
49  }
50
51 private:
52  std::string name_;
53  base::win::ScopedHandle event_;
54  DISALLOW_COPY_AND_ASSIGN(MultiProcessLockWin);
55};
56
57MultiProcessLock* MultiProcessLock::Create(const std::string &name) {
58  return new MultiProcessLockWin(name);
59}
60