Stxxl  1.3.2
state.h
1 /***************************************************************************
2  * include/stxxl/bits/common/state.h
3  *
4  * Part of the STXXL. See http://stxxl.sourceforge.net
5  *
6  * Copyright (C) 2002 Roman Dementiev <[email protected]>
7  * Copyright (C) 2008 Andreas Beckmann <[email protected]>
8  *
9  * Distributed under the Boost Software License, Version 1.0.
10  * (See accompanying file LICENSE_1_0.txt or copy at
11  * http://www.boost.org/LICENSE_1_0.txt)
12  **************************************************************************/
13 
14 #ifndef STXXL_STATE_HEADER
15 #define STXXL_STATE_HEADER
16 
17 #ifdef STXXL_BOOST_THREADS
18  #include <boost/thread/mutex.hpp>
19  #include <boost/thread/condition.hpp>
20 #else
21  #include <pthread.h>
22 #endif
23 
24 #include <stxxl/bits/noncopyable.h>
25 #include <stxxl/bits/common/error_handling.h>
26 
27 
28 __STXXL_BEGIN_NAMESPACE
29 
30 template <typename Tp = int>
31 class state : private noncopyable
32 {
33  typedef Tp value_type;
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  value_type _state;
43 
44 public:
45  state(value_type s) : _state(s)
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 
53  ~state()
54  {
55 #ifndef STXXL_BOOST_THREADS
56  int res = pthread_mutex_trylock(&mutex);
57 
58  if (res == 0 || res == EBUSY) {
59  check_pthread_call(pthread_mutex_unlock(&mutex));
60  } else
61  stxxl_function_error(resource_error);
62  check_pthread_call(pthread_mutex_destroy(&mutex));
63  check_pthread_call(pthread_cond_destroy(&cond));
64 #endif
65  }
66 
67  void set_to(value_type new_state)
68  {
69 #ifdef STXXL_BOOST_THREADS
70  boost::mutex::scoped_lock Lock(mutex);
71  _state = new_state;
72  Lock.unlock();
73  cond.notify_all();
74 #else
75  check_pthread_call(pthread_mutex_lock(&mutex));
76  _state = new_state;
77  check_pthread_call(pthread_mutex_unlock(&mutex));
78  check_pthread_call(pthread_cond_broadcast(&cond));
79 #endif
80  }
81 
82  void wait_for(value_type needed_state)
83  {
84 #ifdef STXXL_BOOST_THREADS
85  boost::mutex::scoped_lock Lock(mutex);
86  while (needed_state != _state)
87  cond.wait(Lock);
88 
89 #else
90  check_pthread_call(pthread_mutex_lock(&mutex));
91  while (needed_state != _state)
92  check_pthread_call(pthread_cond_wait(&cond, &mutex));
93 
94  check_pthread_call(pthread_mutex_unlock(&mutex));
95 #endif
96  }
97 
98  value_type operator () ()
99  {
100 #ifdef STXXL_BOOST_THREADS
101  boost::mutex::scoped_lock Lock(mutex);
102  return _state;
103 #else
104  value_type res;
105  check_pthread_call(pthread_mutex_lock(&mutex));
106  res = _state;
107  check_pthread_call(pthread_mutex_unlock(&mutex));
108  return res;
109 #endif
110  }
111 };
112 
113 __STXXL_END_NAMESPACE
114 
115 #endif // !STXXL_STATE_HEADER