Stxxl
1.4.0
|
00001 /*************************************************************************** 00002 * include/stxxl/bits/common/state.h 00003 * 00004 * Part of the STXXL. See http://stxxl.sourceforge.net 00005 * 00006 * Copyright (C) 2002 Roman Dementiev <dementiev@mpi-sb.mpg.de> 00007 * Copyright (C) 2008 Andreas Beckmann <beckmann@cs.uni-frankfurt.de> 00008 * 00009 * Distributed under the Boost Software License, Version 1.0. 00010 * (See accompanying file LICENSE_1_0.txt or copy at 00011 * http://www.boost.org/LICENSE_1_0.txt) 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