GCS  0.2.3
gu_monitor.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2008 Codership Oy <info@codership.com>
3  *
4  * $Id$
5  */
6 
13 #ifndef __GU_MONITOR_HPP__
14 #define __GU_MONITOR_HPP__
15 
16 #include <gu_lock.hpp>
17 
18 #include <cassert>
19 
20 namespace gu
21 {
22  class Monitor;
23  class Critical;
24 }
25 
27 {
28  int mutable refcnt;
29  Mutex mutex;
30  Cond cond;
31 
32 #ifndef NDEBUG
33  pthread_t mutable holder;
34 #endif
35 
36  // copy contstructor and operator= disabled by mutex and cond members.
37  // but on Darwin, we got an error 'class gu::Monitor' has pointer data members
38  // so make non-copyable explicitly
39  Monitor(const Monitor&);
40  void operator=(const Monitor&);
41 
42 public:
43 
44 #ifndef NDEBUG
45  Monitor() : refcnt(0), mutex(), cond(), holder(0) {}
46 #else
47  Monitor() : refcnt(0), mutex(), cond() {}
48 #endif
49 
50  ~Monitor() {}
51 
52  void enter() const
53  {
54  Lock lock(mutex);
55 
56 // Teemu, pthread_equal() check seems redundant, refcnt too (counted in cond)
57 // while (refcnt > 0 && pthread_equal(holder, pthread_self()) == 0)
58  while (refcnt)
59  {
60  lock.wait(cond);
61  }
62  refcnt++;
63 #ifndef NDEBUG
64  holder = pthread_self();
65 #endif
66  }
67 
68  void leave() const
69  {
70  Lock lock(mutex);
71 
72  assert(refcnt > 0);
73  assert(pthread_equal(holder, pthread_self()) != 0);
74 
75  refcnt--;
76  if (refcnt == 0)
77  {
78  cond.signal();
79  }
80  }
81 };
82 
84 {
85  const Monitor& mon;
86 
87  Critical (const Critical&);
88  Critical& operator= (const Critical&);
89 
90 public:
91 
92  Critical(const Monitor& m) : mon(m)
93  {
94  mon.enter();
95  }
96 
97  ~Critical()
98  {
99  mon.leave();
100  }
101 };
102 
103 
104 #endif /* __GU_MONITOR_HPP__ */
Definition: gu_lock.hpp:20
Definition: gu_mutex.hpp:19
Definition: gu_cond.hpp:19
Definition: gu_monitor.hpp:26
Definition: gu_monitor.hpp:83