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