00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef _GLIBCXX_CONDITION_VARIABLE
00030 #define _GLIBCXX_CONDITION_VARIABLE 1
00031
00032 #pragma GCC system_header
00033
00034 #ifndef __GXX_EXPERIMENTAL_CXX0X__
00035 # include <bits/c++0x_warning.h>
00036 #else
00037
00038 #include <chrono>
00039 #include <mutex>
00040
00041 #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
00042
00043 namespace std _GLIBCXX_VISIBILITY(default)
00044 {
00045 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 enum class cv_status { no_timeout, timeout };
00057
00058
00059 class condition_variable
00060 {
00061 typedef chrono::system_clock __clock_t;
00062 typedef __gthread_cond_t __native_type;
00063 __native_type _M_cond;
00064
00065 public:
00066 typedef __native_type* native_handle_type;
00067
00068 condition_variable() throw ();
00069 ~condition_variable() throw ();
00070
00071 condition_variable(const condition_variable&) = delete;
00072 condition_variable& operator=(const condition_variable&) = delete;
00073
00074 void
00075 notify_one();
00076
00077 void
00078 notify_all();
00079
00080 void
00081 wait(unique_lock<mutex>& __lock);
00082
00083 template<typename _Predicate>
00084 void
00085 wait(unique_lock<mutex>& __lock, _Predicate __p)
00086 {
00087 while (!__p())
00088 wait(__lock);
00089 }
00090
00091 template<typename _Duration>
00092 cv_status
00093 wait_until(unique_lock<mutex>& __lock,
00094 const chrono::time_point<__clock_t, _Duration>& __atime)
00095 { return __wait_until_impl(__lock, __atime); }
00096
00097 template<typename _Clock, typename _Duration>
00098 cv_status
00099 wait_until(unique_lock<mutex>& __lock,
00100 const chrono::time_point<_Clock, _Duration>& __atime)
00101 {
00102
00103 const typename _Clock::time_point __c_entry = _Clock::now();
00104 const __clock_t::time_point __s_entry = __clock_t::now();
00105 const chrono::nanoseconds __delta = __atime - __c_entry;
00106 const __clock_t::time_point __s_atime = __s_entry + __delta;
00107
00108 return __wait_until_impl(__lock, __s_atime);
00109 }
00110
00111 template<typename _Clock, typename _Duration, typename _Predicate>
00112 bool
00113 wait_until(unique_lock<mutex>& __lock,
00114 const chrono::time_point<_Clock, _Duration>& __atime,
00115 _Predicate __p)
00116 {
00117 while (!__p())
00118 if (wait_until(__lock, __atime) == cv_status::timeout)
00119 return __p();
00120 return true;
00121 }
00122
00123 template<typename _Rep, typename _Period>
00124 cv_status
00125 wait_for(unique_lock<mutex>& __lock,
00126 const chrono::duration<_Rep, _Period>& __rtime)
00127 { return wait_until(__lock, __clock_t::now() + __rtime); }
00128
00129 template<typename _Rep, typename _Period, typename _Predicate>
00130 bool
00131 wait_for(unique_lock<mutex>& __lock,
00132 const chrono::duration<_Rep, _Period>& __rtime,
00133 _Predicate __p)
00134 { return wait_until(__lock, __clock_t::now() + __rtime, std::move(__p)); }
00135
00136 native_handle_type
00137 native_handle()
00138 { return &_M_cond; }
00139
00140 private:
00141 template<typename _Clock, typename _Duration>
00142 cv_status
00143 __wait_until_impl(unique_lock<mutex>& __lock,
00144 const chrono::time_point<_Clock, _Duration>& __atime)
00145 {
00146 chrono::time_point<__clock_t, chrono::seconds> __s =
00147 chrono::time_point_cast<chrono::seconds>(__atime);
00148
00149 chrono::nanoseconds __ns =
00150 chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
00151
00152 __gthread_time_t __ts =
00153 {
00154 static_cast<std::time_t>(__s.time_since_epoch().count()),
00155 static_cast<long>(__ns.count())
00156 };
00157
00158 __gthread_cond_timedwait(&_M_cond, __lock.mutex()->native_handle(),
00159 &__ts);
00160
00161 return (_Clock::now() < __atime
00162 ? cv_status::no_timeout : cv_status::timeout);
00163 }
00164 };
00165
00166
00167
00168 class condition_variable_any
00169 {
00170 typedef chrono::system_clock __clock_t;
00171 condition_variable _M_cond;
00172 mutex _M_mutex;
00173
00174 public:
00175 typedef condition_variable::native_handle_type native_handle_type;
00176
00177 condition_variable_any() throw ();
00178 ~condition_variable_any() throw ();
00179
00180 condition_variable_any(const condition_variable_any&) = delete;
00181 condition_variable_any& operator=(const condition_variable_any&) = delete;
00182
00183 void
00184 notify_one()
00185 {
00186 lock_guard<mutex> __lock(_M_mutex);
00187 _M_cond.notify_one();
00188 }
00189
00190 void
00191 notify_all()
00192 {
00193 lock_guard<mutex> __lock(_M_mutex);
00194 _M_cond.notify_all();
00195 }
00196
00197 template<typename _Lock>
00198 void
00199 wait(_Lock& __lock)
00200 {
00201 unique_lock<mutex> __my_lock(_M_mutex);
00202 __lock.unlock();
00203 _M_cond.wait(__my_lock);
00204 __lock.lock();
00205 }
00206
00207
00208 template<typename _Lock, typename _Predicate>
00209 void
00210 wait(_Lock& __lock, _Predicate __p)
00211 {
00212 while (!__p())
00213 wait(__lock);
00214 }
00215
00216 template<typename _Lock, typename _Clock, typename _Duration>
00217 cv_status
00218 wait_until(_Lock& __lock,
00219 const chrono::time_point<_Clock, _Duration>& __atime)
00220 {
00221 unique_lock<mutex> __my_lock(_M_mutex);
00222 __lock.unlock();
00223 cv_status __status = _M_cond.wait_until(__my_lock, __atime);
00224 __lock.lock();
00225 return __status;
00226 }
00227
00228 template<typename _Lock, typename _Clock,
00229 typename _Duration, typename _Predicate>
00230 bool
00231 wait_until(_Lock& __lock,
00232 const chrono::time_point<_Clock, _Duration>& __atime,
00233 _Predicate __p)
00234 {
00235 while (!__p())
00236 if (wait_until(__lock, __atime) == cv_status::timeout)
00237 return __p();
00238 return true;
00239 }
00240
00241 template<typename _Lock, typename _Rep, typename _Period>
00242 cv_status
00243 wait_for(_Lock& __lock, const chrono::duration<_Rep, _Period>& __rtime)
00244 { return wait_until(__lock, __clock_t::now() + __rtime); }
00245
00246 template<typename _Lock, typename _Rep,
00247 typename _Period, typename _Predicate>
00248 bool
00249 wait_for(_Lock& __lock,
00250 const chrono::duration<_Rep, _Period>& __rtime, _Predicate __p)
00251 { return wait_until(__lock, __clock_t::now() + __rtime, std::move(__p)); }
00252
00253 native_handle_type
00254 native_handle()
00255 { return _M_cond.native_handle(); }
00256 };
00257
00258
00259 _GLIBCXX_END_NAMESPACE_VERSION
00260 }
00261
00262 #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
00263
00264 #endif // __GXX_EXPERIMENTAL_CXX0X__
00265
00266 #endif // _GLIBCXX_CONDITION_VARIABLE