@@ -123,12 +123,26 @@ public:
123
123
}
124
124
125
125
const auto _Rel_time_ms = _Clamped_rel_time_ms_count(_Rel_time);
126
- const cv_status _Result = _Wait_for_ms_count(_Lck, _Rel_time_ms._Count);
127
- if (_Rel_time_ms._Clamped) {
128
- return cv_status::no_timeout;
129
- }
130
126
131
- return _Result;
127
+ // wait for signal with timeout
128
+ const shared_ptr<mutex> _Ptr = _Myptr; // for immunity to *this destruction
129
+ const auto _Start = _CHRONO steady_clock::now();
130
+ const auto _Target = _Start + _Rel_time;
131
+
132
+ unique_lock<mutex> _Guard{*_Ptr};
133
+ _Unlock_guard<_Lock> _Unlock_outer{_Lck};
134
+ const _Thrd_result _Res = _Cnd_timedwait_for_unchecked(_Mycnd(), _Ptr->_Mymtx(), _Rel_time_ms._Count);
135
+ _Guard.unlock();
136
+
137
+ if (_Res == _Thrd_result::_Success) {
138
+ return cv_status::no_timeout; // Real or WinAPI-internal spurious wake
139
+ } else if (_Rel_time_ms._Clamped) {
140
+ return cv_status::no_timeout; // Spuriously wake due to clamped timeout
141
+ } else if (_CHRONO steady_clock::now() < _Target) {
142
+ return cv_status::no_timeout; // Spuriously wake due to premature timeout
143
+ } else {
144
+ return cv_status::timeout;
145
+ }
132
146
}
133
147
134
148
template <class _Lock, class _Rep, class _Period, class _Predicate>
@@ -202,7 +216,7 @@ public:
202
216
}
203
217
204
218
const unsigned long _Rel_ms_count = _Clamped_rel_time_ms_count(_Abs_time - _Now)._Count;
205
- (void) _Cnd_timedwait_for (_Mycnd(), _Myptr->_Mymtx(), _Rel_ms_count);
219
+ (void) _Cnd_timedwait_for_unchecked (_Mycnd(), _Myptr->_Mymtx(), _Rel_ms_count);
206
220
_Guard_unlocks_before_locking_outer.unlock();
207
221
} // relock
208
222
@@ -223,22 +237,6 @@ private:
223
237
_NODISCARD _Cnd_t _Mycnd() noexcept {
224
238
return &_Cnd_storage;
225
239
}
226
-
227
- template <class _Lock>
228
- cv_status _Wait_for_ms_count(_Lock& _Lck, const unsigned int _Rel_ms_count) {
229
- // wait for signal with timeout
230
- const shared_ptr<mutex> _Ptr = _Myptr; // for immunity to *this destruction
231
- unique_lock<mutex> _Guard{*_Ptr};
232
- _Unlock_guard<_Lock> _Unlock_outer{_Lck};
233
- const _Thrd_result _Res = _Cnd_timedwait_for(_Mycnd(), _Ptr->_Mymtx(), _Rel_ms_count);
234
- _Guard.unlock();
235
-
236
- if (_Res == _Thrd_result::_Success) {
237
- return cv_status::no_timeout;
238
- } else {
239
- return cv_status::timeout;
240
- }
241
- }
242
240
};
243
241
244
242
_EXPORT_STD inline void notify_all_at_thread_exit(condition_variable& _Cnd, unique_lock<mutex> _Lck) noexcept
0 commit comments