Changeset 6e97265 in mainline for uspace/lib/cpp/include/__bits/thread/shared_state.hpp
- Timestamp:
- 2019-06-30T14:37:40Z (5 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3a29607
- Parents:
- d86c00f0
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/cpp/include/__bits/thread/shared_state.hpp
rd86c00f0 r6e97265 34 34 */ 35 35 36 #include <__bits/exception.hpp> 36 37 #include <__bits/functional/function.hpp> 37 38 #include <__bits/functional/invoke.hpp> 38 39 #include <__bits/refcount_obj.hpp> 40 #include <__bits/thread/future_common.hpp> 39 41 #include <__bits/thread/threading.hpp> 42 #include <cerrno> 43 #include <thread> 44 #include <tuple> 45 46 namespace std 47 { 48 enum class future_status; 49 } 40 50 41 51 namespace std::aux … … 137 147 138 148 template<class Rep, class Period> 139 virtualfuture_status149 future_status 140 150 wait_for(const chrono::duration<Rep, Period>& rel_time) 141 151 { 142 152 aux::threading::mutex::lock(mutex_); 143 auto res = aux::threading::condvar::wait_for( 144 condvar_, mutex_, 153 auto res = timed_wait_( 145 154 aux::threading::time::convert(rel_time) 146 155 ); 147 156 aux::threading::mutex::unlock(mutex_); 148 157 158 return res; 159 } 160 161 template<class Clock, class Duration> 162 future_status 163 wait_until(const chrono::time_point<Clock, Duration>& abs_time) 164 { 165 aux::threading::mutex::lock(mutex_); 166 auto res = timed_wait_( 167 aux::threading::time(convert(abs_time - Clock::now())) 168 ); 169 aux::threading::mutex::unlock(mutex_); 170 171 return res; 172 } 173 174 ~shared_state() override = default; 175 176 protected: 177 aux::mutex_t mutex_; 178 aux::condvar_t condvar_; 179 180 R value_; 181 bool value_set_; 182 183 exception_ptr exception_; 184 bool has_exception_; 185 186 /** 187 * Note: wait_for and wait_until are templates and as such 188 * cannot be virtual and overriden by the deferred_ and 189 * async_ children. However, we are using aux::time_unit_t 190 * in the end anyway, so we can work around that 191 * by using the 'template method' design pattern 192 * (i.e. by providing a virtual function called by these 193 * templates and then overriding that function in the 194 * children). 195 */ 196 virtual future_status timed_wait_(aux::time_unit_t time) 197 { 198 auto res = aux::threading::condvar::wait_for( 199 condvar_, mutex_, time 200 ); 201 149 202 return res == ETIMEOUT ? future_status::timeout 150 203 : future_status::ready; 151 204 } 152 153 template<class Clock, class Duration>154 virtual future_status155 wait_until(const chrono::time_point<Clock, Duration>& abs_time)156 {157 aux::threading::mutex::lock(mutex_);158 auto res = aux::threading::condvar::wait_for(159 condvar_, mutex_,160 aux::threading::time::convert(abs_time - Clock::now())161 );162 aux::threading::mutex::unlock(mutex_);163 164 return res == ETIMEOUT ? future_status::timeout165 : future_status::ready;166 }167 168 ~shared_state() override = default;169 170 private:171 aux::mutex_t mutex_;172 aux::condvar_t condvar_;173 174 R value_;175 bool value_set_;176 177 exception_ptr exception_;178 bool has_exception_;179 205 }; 180 206 … … 224 250 } 225 251 226 template<class Rep, class Period> 227 future_status 228 wait_for(const chrono::duration<Rep, Period>&) override 252 ~async_shared_state() override 253 { 254 destroy(); 255 } 256 257 protected: 258 future_status timed_wait_(aux::time_unit_t) override 229 259 { 230 260 // TODO: have to sleep and check 231 return future_status::ready; 232 } 233 234 template<class Clock, class Duration> 235 future_status 236 wait_until(const chrono::time_point<Clock, Duration>&) override 237 { 238 // TODO: have to sleep and check 239 return future_status::ready; 240 } 241 242 ~async_shared_state() override 243 { 244 destroy(); 261 return future_status::timeout; 245 262 } 246 263 … … 261 278 void destroy() override 262 279 { 263 aux::threading::mutex::lock( mutex_);280 aux::threading::mutex::lock(this->mutex_); 264 281 if (!this->is_set()) 265 282 invoke_(make_index_sequence<sizeof...(Args)>{}); 266 aux::threading::mutex::unlock( mutex_);283 aux::threading::mutex::unlock(this->mutex_); 267 284 } 268 285 269 286 void wait() override 270 287 { 271 aux::threading::mutex::lock(mutex_); 288 /** 289 * Note: Synchronization done in invoke_ -> set_value. 290 */ 272 291 if (!this->is_set()) 273 292 invoke_(make_index_sequence<sizeof...(Args)>{}); 274 aux::threading::mutex::unlock(mutex_);275 }276 277 template<class Rep, class Period>278 future_status279 wait_for(const chrono::duration<Rep, Period>&) override280 {281 /**282 * Note: Neither of the wait_ functions has any effect283 * for deferred functions spawned by async (which284 * are the only users of this state type).285 */286 return future_status::deferred;287 }288 289 template<class Clock, class Duration>290 future_status291 wait_until(const chrono::time_point<Clock, Duration>&) override292 {293 return future_status::deferred;294 293 } 295 294 … … 299 298 } 300 299 301 pr ivate:300 protected: 302 301 function<R(decay_t<Args>...)> func_; 303 302 tuple<decay_t<Args>...> args_; … … 315 314 } 316 315 } 316 317 future_status timed_wait_(aux::time_unit_t) override 318 { 319 /** 320 * Note: Neither of the wait_ functions has any effect 321 * for deferred functions spawned by async (which 322 * are the only users of this state type). 323 */ 324 return future_status::deferred; 325 } 317 326 }; 318 327 }
Note:
See TracChangeset
for help on using the changeset viewer.