Changeset 60cb9e1 in mainline
- Timestamp:
- 2019-07-01T09:50:26Z (5 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d340254
- Parents:
- bd6ad4b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/cpp/include/__bits/thread/shared_state.hpp
rbd6ad4b r60cb9e1 44 44 #include <tuple> 45 45 46 namespace std47 {48 enum class future_status;49 }50 51 46 namespace std::aux 52 47 { 53 template<class R> 54 class shared_state: public aux::refcount_obj 55 { 56 public: 57 shared_state() 58 : mutex_{}, condvar_{}, value_{}, value_set_{false}, 48 /** 49 * TODO: Make this a shared_state_base which will not have the 50 * set_value functions, but will keep the rest. Then create 51 * shared state with the set_value function and a specialization 52 * of that with a set_value that takes no arguments. 53 * 54 * The value itself should be in the children (as the void one 55 * won't have it). 56 */ 57 class shared_state_base: public aux::refcount_obj 58 { 59 public: 60 shared_state_base() 61 : mutex_{}, condvar_{}, value_set_{false}, 59 62 exception_{}, has_exception_{false} 60 63 { … … 72 75 } 73 76 74 void set_value(const R& val, bool set) 75 { 76 /** 77 * Note: This is the 'mark ready' move described 78 * in 30.6.4 (6). 79 */ 80 81 aux::threading::mutex::lock(mutex_); 82 value_ = val; 77 void mark_set(bool set = true) noexcept 78 { 83 79 value_set_ = set; 84 aux::threading::mutex::unlock(mutex_);85 86 aux::threading::condvar::broadcast(condvar_);87 }88 89 void set_value(R&& val, bool set = true)90 {91 aux::threading::mutex::lock(mutex_);92 value_ = std::move(val);93 value_set_ = set;94 aux::threading::mutex::unlock(mutex_);95 96 aux::threading::condvar::broadcast(condvar_);97 }98 99 void mark_set(bool set = true) noexcept100 {101 value_set_ = set;102 80 } 103 81 … … 105 83 { 106 84 return value_set_; 107 }108 109 R& get()110 {111 return value_;112 85 } 113 86 … … 165 138 aux::threading::mutex::lock(mutex_); 166 139 auto res = timed_wait_( 167 aux::threading::time (convert(abs_time - Clock::now()))140 aux::threading::time::convert(abs_time - Clock::now()) 168 141 ); 169 142 aux::threading::mutex::unlock(mutex_); … … 172 145 } 173 146 174 ~shared_state () override = default;147 ~shared_state_base() override = default; 175 148 176 149 protected: … … 178 151 aux::condvar_t condvar_; 179 152 180 R value_;181 153 bool value_set_; 182 154 … … 205 177 }; 206 178 179 template<class R> 180 class shared_state: public shared_state_base 181 { 182 public: 183 shared_state() 184 : shared_state_base{} 185 { /* DUMMY BODY */ } 186 187 void set_value(const R& val, bool set) 188 { 189 /** 190 * Note: This is the 'mark ready' move described 191 * in 30.6.4 (6). 192 */ 193 194 aux::threading::mutex::lock(mutex_); 195 value_ = val; 196 value_set_ = set; 197 aux::threading::mutex::unlock(mutex_); 198 199 aux::threading::condvar::broadcast(condvar_); 200 } 201 202 void set_value(R&& val, bool set = true) 203 { 204 aux::threading::mutex::lock(mutex_); 205 value_ = std::move(val); 206 value_set_ = set; 207 aux::threading::mutex::unlock(mutex_); 208 209 aux::threading::condvar::broadcast(condvar_); 210 } 211 212 R& get() 213 { 214 return value_; 215 } 216 217 protected: 218 R value_; 219 }; 220 221 template<> 222 class shared_state<void>: public shared_state_base 223 { 224 public: 225 shared_state() 226 : shared_state_base{} 227 { /* DUMMY BODY */ } 228 229 void set_value() 230 { 231 value_set_ = true; 232 aux::threading::condvar::broadcast(condvar_); 233 } 234 235 void get() 236 { /* DUMMY BODY */ } 237 }; 238 207 239 /** 208 240 * We could make one state for both async and … … 215 247 * But since we have no plan (nor need) to make those, 216 248 * this approach seems to be the best one. 249 * 250 * Also note that unlike the parent class shared_state, 251 * we do not need to specialize these for void. This is because 252 * the difference in class contents are handled by the parent 253 * specialization and setting the value can be handled easily 254 * by if constexpr and checking for the equivalence of the 255 * R template parameter and void. 217 256 */ 218 257 … … 228 267 try 229 268 { 230 this->set_value(invoke(f, args...)); 269 if constexpr (!is_same_v<R, void>) 270 this->set_value(invoke(f, args...)); 271 else 272 { 273 invoke(f, args...); 274 this->mark_set(true); 275 } 231 276 } 232 277 catch(...) // TODO: Any exception. … … 307 352 try 308 353 { 309 this->set_value(invoke(move(func_), get<Is>(move(args_))...)); 354 if constexpr (!is_same_v<R, void>) 355 this->set_value(invoke(move(func_), get<Is>(move(args_))...)); 356 else 357 { 358 invoke(move(func_), get<Is>(move(args_))...); 359 this->mark_set(true); 360 } 310 361 } 311 362 catch(...)
Note:
See TracChangeset
for help on using the changeset viewer.