1// Copyright 2014 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#ifndef MOJO_PUBLIC_CPP_UTILITY_MUTEX_H_
6#define MOJO_PUBLIC_CPP_UTILITY_MUTEX_H_
7
8#ifdef _WIN32
9#error "Not implemented: See crbug.com/342893."
10#endif
11
12#include <pthread.h>
13
14#include "mojo/public/cpp/system/macros.h"
15
16namespace mojo {
17
18#ifdef NDEBUG
19// Note: Make a C++ constant for |PTHREAD_MUTEX_INITIALIZER|. (We can't directly
20// use the C macro in an initializer list, since it might expand to |{ ... }|.)
21namespace internal {
22const pthread_mutex_t kPthreadMutexInitializer = PTHREAD_MUTEX_INITIALIZER;
23}
24#endif
25
26class Mutex {
27 public:
28#ifdef NDEBUG
29  Mutex() : mutex_(internal::kPthreadMutexInitializer) {}
30  ~Mutex() { pthread_mutex_destroy(&mutex_); }
31
32  void Lock() { pthread_mutex_lock(&mutex_); }
33  void Unlock() { pthread_mutex_unlock(&mutex_); }
34  bool TryLock() { return pthread_mutex_trylock(&mutex_) == 0; }
35
36  void AssertHeld() {}
37#else
38  Mutex();
39  ~Mutex();
40
41  void Lock();
42  void Unlock();
43  bool TryLock();
44
45  void AssertHeld();
46#endif
47
48 private:
49  pthread_mutex_t mutex_;
50
51  MOJO_DISALLOW_COPY_AND_ASSIGN(Mutex);
52};
53
54class MutexLock {
55 public:
56  explicit MutexLock(Mutex* mutex) : mutex_(mutex) { mutex_->Lock(); }
57  ~MutexLock() { mutex_->Unlock(); }
58
59 private:
60  Mutex* const mutex_;
61
62  MOJO_DISALLOW_COPY_AND_ASSIGN(MutexLock);
63};
64
65// Catch bug where variable name is omitted (e.g., |MutexLock (&mu)|).
66#define MutexLock(x) MOJO_COMPILE_ASSERT(0, mutex_lock_missing_variable_name);
67
68}  // namespace mojo
69
70#endif  // MOJO_PUBLIC_CPP_UTILITY_MUTEX_H_
71