| 1182 | |
| 1183 | template <typename T> |
| 1184 | T SyncVar<T>::read() { |
| 1185 | _lock.lock(); |
| 1186 | if (_set) { |
| 1187 | _lock.unlock(); |
| 1188 | return _value; |
| 1189 | } |
| 1190 | if (_sem.is_null()) { |
| 1191 | _sem = vnew<Semaphore>(); |
| 1192 | } |
| 1193 | // We can't wait inside the lock without deadlocking; but waiting outside |
| 1194 | // could cause a race condition with _sem being freed due to being idle. |
| 1195 | // Thus, we use start_wait() to insert ourselves into the queue, then |
| 1196 | // use wait_signal() outside the lock to complete waiting. |
| 1197 | // |
| 1198 | // Note: start_wait() will not send a signal to self, as _set is |
| 1199 | // false and therefore _sem->value() must be zero. |
| 1200 | _sem->start_wait(0); |
| 1201 | _lock.unlock(); |
| 1202 | internals::wait_signal(); |
| 1203 | _lock.lock(); |
| 1204 | if (_sem->_idle()) |
| 1205 | _sem->post(); |
| 1206 | else { |
| 1207 | _sem.free(); |
| 1208 | _sem = vnull<Semaphore>(); |
| 1209 | } |
| 1210 | _lock.unlock(); |
| 1211 | return _value; |
| 1212 | } |
| 1213 | |
| 1214 | template <typename T> |
| 1215 | Result<T> SyncVar<T>::try_read() { |
no test coverage detected