00001 #ifndef DV_THREAD_MONITOR_H 00002 #define DV_THREAD_MONITOR_H 00003 // $Id: monitor.h,v 1.19 2008/12/21 09:40:47 dvermeir Exp $ 00004 00005 #include <string> 00006 #include <iostream> 00007 #include <stdexcept> 00008 extern "C" { 00009 #include <pthread.h> // posix thread library 00010 } 00011 #include <sys/time.h> 00012 #include <dvutil/debug.h> 00013 00014 namespace Dv { 00015 namespace Thread { 00016 /** 00017 * A simple Monitor class using posix threads. 00018 * 00019 * The following defines a Buffer monitor with protected 00020 * get() and put() access. 00021 * @example test-buffer.h 00022 * 00023 * @see Dv::Thread::Thread 00024 */ 00025 class Monitor: public Dv::DebugSlave { 00026 public: 00027 /** Constructor. 00028 * @param name of this monitor. 00029 * @param n_conditions number of conditions in this monitor. 00030 * @param min_debug_level if a debug_master is connected, logging info 00031 * will only be written if the master's level is at least @a min_debug_level 00032 * @param debug_master from where debug info will be taken 00033 * @sa Dv::DebugSlave 00034 */ 00035 Monitor(const std::string& name, unsigned int n_conditions=0, 00036 unsigned int min_debug_level = 0, Debugable* debug_master=0); 00037 /** Virtual destructor. */ 00038 virtual ~Monitor(); 00039 /** Enter the monitor. 00040 * @exception std::runtime_error if this thread already owns the monitor 00041 */ 00042 void enter(const std::string* msg = 0); 00043 /** Exit the monitor. 00044 * @exception std::runtime_error if this thread is not the current owner of the monitor 00045 */ 00046 void exit(const std::string* msg = 0); 00047 /** Unconditionally wait for a given condition. 00048 * @param condition number of the condition to wait for. 00049 * @exception std::runtime_error if this thread is not the current owner of the monitor 00050 */ 00051 void wait(unsigned int condition=0); 00052 /** Wait for a given condition or until timeout millisecs elapsed. 00053 * @param condition number of the condition to wait for. 00054 * @param timeout number of milliseconds we are prepared to wait. 00055 * @return false if a timeout occured. 00056 * @exception std::runtime_error if this thread is not the current owner of the monitor 00057 */ 00058 bool wait(unsigned int condition, time_t timeout); 00059 /** Signal a given condition. This function unblocks at least one 00060 * thread blocked on the condition. The unblocked threads contend 00061 * for the monitor. 00062 * @param condition to signal. 00063 * @exception runtime_error if this thread is not the current owner of the monitor 00064 */ 00065 void signal(unsigned int condition=0) const; 00066 /** Signal all threads waiting on this condition. 00067 * This function unblocks all the threads blocked on the condition. 00068 * The unblocked threads compete for the monitor. 00069 * @param condition to signal. 00070 * @exception runtime_error if this thread is not the current owner of the monitor 00071 */ 00072 void broadcast(unsigned int condition=0) const; 00073 /** @return name of this monitor. */ 00074 const std::string& name() const { return name_; } 00075 00076 /** @return id of thread currently owning the monitor */ 00077 pthread_t owner() const { return owner_; } 00078 00079 /** @return true iff the current thread is the owner of the monitor. */ 00080 bool owned_by_self() const { 00081 return pthread_equal(owner(), pthread_self()); 00082 } 00083 00084 private: 00085 /** Name of the monitor. */ 00086 std::string name_; 00087 /** Thread that currently owns the monitor. */ 00088 pthread_t owner_; 00089 /** Entry to the monitor is controlled by this mutex semaphore. */ 00090 pthread_mutex_t mutex_; 00091 /** Attributes of mutex_. */ 00092 pthread_mutexattr_t mutex_attributes_; 00093 /** Number of conditions of the monitor. */ 00094 unsigned int n_conditions_; 00095 /** Array of n_conditions_ posix conditions of this monitor. */ 00096 pthread_cond_t* conditions_; 00097 pthread_condattr_t condition_attributes_; 00098 /** This functions throws a std::runtime_error if the current thread 00099 * is not the current owner of the monitor. 00100 * @param message used as part of runtime_error.what() 00101 * @exception std::runtime_error if this thread is not the current owner of the monitor 00102 */ 00103 void check(const std::string& message) const; 00104 /** This functions throws a runtime_error if n is not a valid 00105 * condition of this monitor or if the current thread does not 00106 * own the monitor. 00107 * @param msg used as part of runtime_error.what() 00108 * @param n number of condition to check 00109 * @exception std::runtime_error if this thread is not the current owner of the monitor 00110 */ 00111 void check_cond(const std::string& msg,unsigned int n) const; 00112 00113 /** No copy ctor. */ 00114 Monitor(const Monitor&); 00115 /** No assignment operator. */ 00116 Monitor& operator=(const Monitor&); 00117 00118 }; 00119 } 00120 } 00121 00122 #endif
dvthread-0.13.4 | [11 December, 2009] |