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/utf_string_conversions.h"
94a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "base/win/scoped_handle.h"
104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochclass MultiProcessLockWin : public MultiProcessLock {
124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch public:
134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  explicit MultiProcessLockWin(const std::string& name) : name_(name) { }
144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
154a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  virtual ~MultiProcessLockWin() {
164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    if (event_.Get() != NULL) {
174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      Unlock();
184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    }
194a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  virtual bool TryLock() {
224a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    if (event_.Get() != 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    string16 wname = UTF8ToUTF16(name_);
344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    event_.Set(CreateEvent(NULL, FALSE, FALSE, wname.c_str()));
354a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    if (event_.Get() && GetLastError() != ERROR_ALREADY_EXISTS) {
364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      return true;
374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    } else {
384a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      event_.Set(NULL);
394a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      return false;
404a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    }
414a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
424a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
434a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  virtual void Unlock() {
444a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    if (event_.Get() == NULL) {
454a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      DLOG(ERROR) << "Over-unlocked MultiProcessLock - " << name_;
464a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      return;
474a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    }
484a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    event_.Set(NULL);
494a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
504a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
514a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch private:
524a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  std::string name_;
534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  base::win::ScopedHandle event_;
544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(MultiProcessLockWin);
554a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch};
564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
574a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben MurdochMultiProcessLock* MultiProcessLock::Create(const std::string &name) {
584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  return new MultiProcessLockWin(name);
594a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
60