00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef STXXL_STATE_HEADER
00015 #define STXXL_STATE_HEADER
00016
00017 #ifdef STXXL_BOOST_THREADS
00018 #include <boost/thread/mutex.hpp>
00019 #include <boost/thread/condition.hpp>
00020 #else
00021 #include <pthread.h>
00022 #endif
00023
00024 #include <stxxl/bits/noncopyable.h>
00025 #include <stxxl/bits/common/error_handling.h>
00026
00027
00028 __STXXL_BEGIN_NAMESPACE
00029
00030 template <typename Tp = int>
00031 class state : private noncopyable
00032 {
00033 typedef Tp value_type;
00034
00035 #ifdef STXXL_BOOST_THREADS
00036 boost::mutex mutex;
00037 boost::condition cond;
00038 #else
00039 pthread_mutex_t mutex;
00040 pthread_cond_t cond;
00041 #endif
00042 value_type _state;
00043
00044 public:
00045 state(value_type s) : _state(s)
00046 {
00047 #ifndef STXXL_BOOST_THREADS
00048 check_pthread_call(pthread_mutex_init(&mutex, NULL));
00049 check_pthread_call(pthread_cond_init(&cond, NULL));
00050 #endif
00051 }
00052
00053 ~state()
00054 {
00055 #ifndef STXXL_BOOST_THREADS
00056 int res = pthread_mutex_trylock(&mutex);
00057
00058 if (res == 0 || res == EBUSY) {
00059 check_pthread_call(pthread_mutex_unlock(&mutex));
00060 } else
00061 stxxl_function_error(resource_error);
00062 check_pthread_call(pthread_mutex_destroy(&mutex));
00063 check_pthread_call(pthread_cond_destroy(&cond));
00064 #endif
00065 }
00066
00067 void set_to(value_type new_state)
00068 {
00069 #ifdef STXXL_BOOST_THREADS
00070 boost::mutex::scoped_lock Lock(mutex);
00071 _state = new_state;
00072 Lock.unlock();
00073 cond.notify_all();
00074 #else
00075 check_pthread_call(pthread_mutex_lock(&mutex));
00076 _state = new_state;
00077 check_pthread_call(pthread_mutex_unlock(&mutex));
00078 check_pthread_call(pthread_cond_broadcast(&cond));
00079 #endif
00080 }
00081
00082 void wait_for(value_type needed_state)
00083 {
00084 #ifdef STXXL_BOOST_THREADS
00085 boost::mutex::scoped_lock Lock(mutex);
00086 while (needed_state != _state)
00087 cond.wait(Lock);
00088
00089 #else
00090 check_pthread_call(pthread_mutex_lock(&mutex));
00091 while (needed_state != _state)
00092 check_pthread_call(pthread_cond_wait(&cond, &mutex));
00093
00094 check_pthread_call(pthread_mutex_unlock(&mutex));
00095 #endif
00096 }
00097
00098 value_type operator () ()
00099 {
00100 #ifdef STXXL_BOOST_THREADS
00101 boost::mutex::scoped_lock Lock(mutex);
00102 return _state;
00103 #else
00104 value_type res;
00105 check_pthread_call(pthread_mutex_lock(&mutex));
00106 res = _state;
00107 check_pthread_call(pthread_mutex_unlock(&mutex));
00108 return res;
00109 #endif
00110 }
00111 };
00112
00113 __STXXL_END_NAMESPACE
00114
00115 #endif // !STXXL_STATE_HEADER