Stxxl  1.4.0
include/stxxl/bits/common/state.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines