00001 // more/thread.h -- a thread class: POSIX implementation 00002 // Copyright (C) 1998--2002 Petter Urkedal 00003 00004 // This file is free software; you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation; either version 2 of the License, or 00007 // (at your option) any later version. 00008 00009 // This file is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 00014 // You should have received a copy of the GNU General Public License 00015 // along with this program; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 // As a special exception, you may use this file as part of a free 00019 // software library without restriction. Specifically, if other files 00020 // instantiate templates or use macros or inline functions from this 00021 // file, or you compile this file and link it with other files to 00022 // produce an executable, this file does not by itself cause the 00023 // resulting executable to be covered by the GNU General Public 00024 // License. This exception does not however invalidate any other 00025 // reasons why the executable file might be covered by the GNU General 00026 // Public License. 00027 00028 // $Id: thread.h,v 1.2 2002/08/24 13:59:38 petter_urkedal Exp $ 00029 00030 00031 #ifndef MORE_CF_THREAD_H 00032 #define MORE_CF_THREAD_H 00033 00034 #include <exception> 00035 #include <stdexcept> 00036 #include <more/bits/configdefs.h> 00037 #include <more/gen/utility.h> 00038 #include <more/gen/closure.h> 00039 #include <more/cf/threadfwd.h> 00040 00041 00042 namespace more { 00043 namespace cf { 00044 00045 00046 //-------------------------------------------------------------------- 00047 // mutex 00048 //-------------------------------------------------------------------- 00049 00050 class mutex_data; 00051 00052 /** Mutual exclusive lock. Mutex locks are used to prevent 00053 different threads from accessing the same collection of 00054 interdependent data simultaneously. If the conditions given for 00055 the member functions are violated, a logic_error will be thrown. 00056 Also, runtime_error may be throw in case of lack of 00057 resources. */ 00058 struct mutex : gen::handle<mutex_data> 00059 { 00060 friend class mutex_data; 00061 00062 //! The non-trivial default ctor initializes a new mutex. 00063 mutex(); 00064 00065 //! Copy ctor with shallow-copy semantic. 00066 mutex(mutex const&); 00067 00068 //! Destructor. 00069 /*! The destructor requires that the mutex is currently unlocked. */ 00070 ~mutex(); 00071 00072 //! Assignment with shallow-copy semantic. 00073 mutex& operator=(mutex const&); 00074 00075 //! Lock the mutex. 00076 /*! The mutex must not be already locked in the same thread. If 00077 * it is locked by another thread, this call will suspend the 00078 * current thread until it is unlocked. */ 00079 void lock(); 00080 00081 //! Lock the mutex if it is unlocked. 00082 /*! Same as lock(), except that when the mutex is locked by 00083 * another thread, this call exits with false. Otherwise it 00084 * exits with true. */ 00085 bool trylock(); 00086 00087 //! Unlock a mutex. 00088 // The mutex must be previously locked by the current thread. 00089 void unlock(); 00090 }; 00091 00092 00093 00094 //-------------------------------------------------------------------- 00095 // thread 00096 //-------------------------------------------------------------------- 00097 00098 class thread_data; 00099 00100 /** A descriptor for creating and controlling a thread. */ 00101 class thread : gen::handle<thread_data> 00102 { 00103 typedef gen::generator_closure<void> closure_type; 00104 00105 public: 00106 /** Construct an undefined thread object. This object becomes 00107 defined afther assigning another thread object or calling 00108 set_call. */ 00109 thread(); 00110 00111 /** Construct a shallow copy of x. */ 00112 thread(thread const& x); 00113 00114 /** Destruct a thread descriptor. The thread data will be 00115 released when all instances of thread is out of scope and 00116 the thread has returned. */ 00117 ~thread(); 00118 00119 /** Construct a thread which will run the given closure when 00120 started. This is equivalend to default construction 00121 followed by a set_call. */ 00122 explicit thread(closure_type const&); 00123 00124 /** Assign a shallow copy of x. */ 00125 thread& operator=(thread const& x); 00126 00127 private: 00128 explicit thread(thread_data*); 00129 00130 public: 00131 /** Returns is_defined(). */ 00132 operator bool() { return this->data(); } 00133 00134 /** Set the closure to call. The thread must not have been 00135 started. */ 00136 void set_call(closure_type const&); 00137 00138 /** True iff a closue has been assigned to the thread. */ 00139 bool is_defined() const; 00140 00141 /** True iff the thread has been started. */ 00142 bool is_started() const; 00143 00144 /** True iff the thread is started and has not yet returned. */ 00145 bool is_active() const; 00146 00147 /** True iff the thread is running. */ 00148 bool is_running() const; 00149 00150 /** True iff the thread has returned. */ 00151 bool is_finished() const; 00152 00153 /** True iff the thread cancel() method has been called for this 00154 thread. The thread has not necessarily acknowledged this 00155 and may still be running. */ 00156 bool is_canceled() const; 00157 00158 /** True iff an exception was raised in the thread. Implies 00159 is_finished(). */ 00160 bool is_excepted() const; 00161 00162 /** Start the given closure in a new thread. */ 00163 void start(); 00164 00165 /** Throw a thread_cancel exception in the thread. The 00166 cancellation will be acknowledged only after the code calls 00167 checkpoint(). */ 00168 void cancel(); 00169 00170 /** Wait for a thread to stop. Uncaught exceptions, but not 00171 thread_canceled, will be rethrown, but with loss of 00172 type-information. That is, exceptions derived from 00173 exception, logic_error or runtime error will be rethrown as 00174 this base class. */ 00175 bool join(); // returns true if computation is complete 00176 00177 friend class thread_data; 00178 friend thread thread_of_caller(); 00179 }; 00180 00181 /** True iff cancel is requested for this thread. */ 00182 bool caller_is_canceled(); 00183 00184 #if MORE_BW(20011111) 00185 /** DON'T USE, backward compatibility. */ 00186 inline bool is_canceled() { return caller_is_canceled(); } 00187 #endif 00188 00189 /** The thread descriptor of the thread from which this function is 00190 called. The main thread returns an undefined descriptor at the 00191 moment, though this may change. */ 00192 thread thread_of_caller(); 00193 00194 /** The exception thrown by checkpoint() if cancel() is called on 00195 the current thread. */ 00196 struct thread_canceled {}; 00197 00198 }} // namespace more::cf 00199 00200 #endif