15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/multi_process_lock.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_handle.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MultiProcessLockWin : public MultiProcessLock {
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit MultiProcessLockWin(const std::string& name) : name_(name) { }
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~MultiProcessLockWin() {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event_.Get() != NULL) {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Unlock();
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool TryLock() {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event_.Get() != NULL) {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DLOG(ERROR) << "MultiProcessLock is already locked - " << name_;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (name_.length() >= MAX_PATH) {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Socket name too long (" << name_.length()
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << " >= " << MAX_PATH << ") - " << name_;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::string16 wname = base::UTF8ToUTF16(name_);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    event_.Set(CreateEvent(NULL, FALSE, FALSE, wname.c_str()));
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event_.Get() && GetLastError() != ERROR_ALREADY_EXISTS) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      event_.Set(NULL);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Unlock() {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event_.Get() == NULL) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DLOG(ERROR) << "Over-unlocked MultiProcessLock - " << name_;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    event_.Set(NULL);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string name_;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::ScopedHandle event_;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MultiProcessLockWin);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MultiProcessLock* MultiProcessLock::Create(const std::string &name) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new MultiProcessLockWin(name);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
60