Stxxl  1.3.2
switch.h
1 /***************************************************************************
2  * include/stxxl/bits/common/switch.h
3  *
4  * kind of semaphore
5  *
6  * Part of the STXXL. See http://stxxl.sourceforge.net
7  *
8  * Copyright (C) 2002 Roman Dementiev <[email protected]>
9  *
10  * Distributed under the Boost Software License, Version 1.0.
11  * (See accompanying file LICENSE_1_0.txt or copy at
12  * http://www.boost.org/LICENSE_1_0.txt)
13  **************************************************************************/
14 
15 #ifndef STXXL_SWITCH_HEADER
16 #define STXXL_SWITCH_HEADER
17 
18 #ifdef STXXL_BOOST_THREADS
19  #include <boost/thread/mutex.hpp>
20  #include <boost/thread/condition.hpp>
21 #else
22  #include <pthread.h>
23 #endif
24 
25 #include <stxxl/bits/noncopyable.h>
26 #include <stxxl/bits/common/error_handling.h>
27 
28 
29 __STXXL_BEGIN_NAMESPACE
30 
31 //#define onoff_switch Switch
32 
33 class onoff_switch : private noncopyable
34 {
35 #ifdef STXXL_BOOST_THREADS
36  boost::mutex mutex;
37  boost::condition cond;
38 #else
39  pthread_mutex_t mutex;
40  pthread_cond_t cond;
41 #endif
42  bool _on;
43 
44 public:
45  onoff_switch(bool flag = false) : _on(flag)
46  {
47 #ifndef STXXL_BOOST_THREADS
48  check_pthread_call(pthread_mutex_init(&mutex, NULL));
49  check_pthread_call(pthread_cond_init(&cond, NULL));
50 #endif
51  }
52  ~onoff_switch()
53  {
54 #ifndef STXXL_BOOST_THREADS
55  int res = pthread_mutex_trylock(&mutex);
56 
57  if (res == 0 || res == EBUSY) {
58  check_pthread_call(pthread_mutex_unlock(&mutex));
59  } else
60  stxxl_function_error(resource_error);
61  check_pthread_call(pthread_mutex_destroy(&mutex));
62 
63 
64  check_pthread_call(pthread_cond_destroy(&cond));
65 #endif
66  }
67  void on()
68  {
69 #ifdef STXXL_BOOST_THREADS
70  boost::mutex::scoped_lock Lock(mutex);
71  _on = true;
72  Lock.unlock();
73  cond.notify_one();
74 #else
75  check_pthread_call(pthread_mutex_lock(&mutex));
76  _on = true;
77  check_pthread_call(pthread_mutex_unlock(&mutex));
78  check_pthread_call(pthread_cond_signal(&cond));
79 #endif
80  }
81  void off()
82  {
83 #ifdef STXXL_BOOST_THREADS
84  boost::mutex::scoped_lock Lock(mutex);
85  _on = false;
86  Lock.unlock();
87  cond.notify_one();
88 #else
89  check_pthread_call(pthread_mutex_lock(&mutex));
90  _on = false;
91  check_pthread_call(pthread_mutex_unlock(&mutex));
92  check_pthread_call(pthread_cond_signal(&cond));
93 #endif
94  }
95  void wait_for_on()
96  {
97 #ifdef STXXL_BOOST_THREADS
98  boost::mutex::scoped_lock Lock(mutex);
99  if (!_on)
100  cond.wait(Lock);
101 
102 #else
103  check_pthread_call(pthread_mutex_lock(&mutex));
104  if (!_on)
105  check_pthread_call(pthread_cond_wait(&cond, &mutex));
106 
107  check_pthread_call(pthread_mutex_unlock(&mutex));
108 #endif
109  }
110  void wait_for_off()
111  {
112 #ifdef STXXL_BOOST_THREADS
113  boost::mutex::scoped_lock Lock(mutex);
114  if (_on)
115  cond.wait(Lock);
116 
117 #else
118  check_pthread_call(pthread_mutex_lock(&mutex));
119  if (_on)
120  check_pthread_call(pthread_cond_wait(&cond, &mutex));
121 
122  check_pthread_call(pthread_mutex_unlock(&mutex));
123 #endif
124  }
125  bool is_on()
126  {
127 #ifdef STXXL_BOOST_THREADS
128  boost::mutex::scoped_lock Lock(mutex);
129  return _on;
130 #else
131  bool res;
132  check_pthread_call(pthread_mutex_lock(&mutex));
133  res = _on;
134  check_pthread_call(pthread_mutex_unlock(&mutex));
135  return res;
136 #endif
137  }
138 };
139 
140 __STXXL_END_NAMESPACE
141 
142 #endif // !STXXL_SWITCH_HEADER