203
204
/** Goto avoidance. */
204
DECL_FORCE_INLINE(int) rtSemEventWaitHandleStatus(struct RTSEMEVENTMULTIINTERNAL *pThis, DWORD rc)
205
DECL_FORCE_INLINE(int)
206
rtSemEventWaitHandleStatus(struct RTSEMEVENTMULTIINTERNAL *pThis, uint32_t fFlags, DWORD rc)
208
210
case WAIT_OBJECT_0: return VINF_SUCCESS;
209
211
case WAIT_TIMEOUT: return VERR_TIMEOUT;
210
case WAIT_IO_COMPLETION: return VERR_INTERRUPTED;
212
case WAIT_IO_COMPLETION: return fFlags & RTSEMWAIT_FLAGS_RESUME ? VERR_TIMEOUT : VERR_INTERRUPTED;
211
213
case WAIT_ABANDONED: return VERR_SEM_OWNER_DIED;
213
215
AssertMsgFailed(("%u\n", rc));
228
#undef RTSemEventMultiWaitNoResume
229
RTDECL(int) RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies)
230
DECLINLINE(int) rtSemEventMultiWinWait(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout,
231
PCRTLOCKVALSRCPOS pSrcPos)
231
PCRTLOCKVALSRCPOS pSrcPos = NULL;
234
234
* Validate input.
236
236
struct RTSEMEVENTMULTIINTERNAL *pThis = hEventMultiSem;
237
237
AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
238
238
AssertReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, VERR_INVALID_HANDLE);
241
* Wait for condition.
239
AssertReturn(RTSEMWAIT_FLAGS_ARE_VALID(fFlags), VERR_INVALID_PARAMETER);
242
* Convert the timeout to a millisecond count.
244
uint64_t uAbsDeadline;
246
if (fFlags & RTSEMWAIT_FLAGS_INDEFINITE)
248
dwMsTimeout = INFINITE;
249
uAbsDeadline = UINT64_MAX;
253
if (fFlags & RTSEMWAIT_FLAGS_NANOSECS)
254
uTimeout = uTimeout < UINT64_MAX - UINT32_C(1000000) / 2
255
? (uTimeout + UINT32_C(1000000) / 2) / UINT32_C(1000000)
256
: UINT64_MAX / UINT32_C(1000000);
257
if (fFlags & RTSEMWAIT_FLAGS_ABSOLUTE)
259
uAbsDeadline = uTimeout;
260
uint64_t u64Now = RTTimeSystemMilliTS();
261
if (u64Now < uTimeout)
266
else if (fFlags & RTSEMWAIT_FLAGS_RESUME)
267
uAbsDeadline = RTTimeSystemMilliTS() + uTimeout;
269
uAbsDeadline = UINT64_MAX;
271
dwMsTimeout = uTimeout < UINT32_MAX
243
280
#ifdef RTSEMEVENT_STRICT
244
281
RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
245
282
if (pThis->fEverHadSignallers)
247
DWORD rc = WaitForSingleObjectEx(pThis->hev,
249
TRUE /*fAlertable*/);
250
if (rc != WAIT_TIMEOUT || cMillies == 0)
251
return rtSemEventWaitHandleStatus(pThis, rc);
285
rc = WaitForSingleObjectEx(pThis->hev, 0 /*Timeout*/, TRUE /*fAlertable*/);
286
while (rc == WAIT_IO_COMPLETION && (fFlags & RTSEMWAIT_FLAGS_RESUME));
287
if (rc != WAIT_TIMEOUT || dwMsTimeout == 0)
288
return rtSemEventWaitHandleStatus(pThis, fFlags, rc);
252
289
int rc9 = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false,
253
cMillies, RTTHREADSTATE_EVENT_MULTI, true);
290
dwMsTimeout, RTTHREADSTATE_EVENT_MULTI, true);
254
291
if (RT_FAILURE(rc9))
258
295
RTTHREAD hThreadSelf = RTThreadSelf();
260
297
RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT_MULTI, true);
261
DWORD rc = WaitForSingleObjectEx(pThis->hev,
262
cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies,
263
TRUE /*fAlertable*/);
298
rc = WaitForSingleObjectEx(pThis->hev, dwMsTimeout, TRUE /*fAlertable*/);
299
if (rc == WAIT_IO_COMPLETION && (fFlags & RTSEMWAIT_FLAGS_RESUME))
301
while ( rc == WAIT_IO_COMPLETION
302
&& RTTimeSystemMilliTS() < uAbsDeadline)
303
rc = WaitForSingleObjectEx(pThis->hev, dwMsTimeout, TRUE /*fAlertable*/);
264
306
RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT_MULTI);
265
return rtSemEventWaitHandleStatus(pThis, rc);
307
return rtSemEventWaitHandleStatus(pThis, fFlags, rc);
312
#undef RTSemEventMultiWaitEx
313
RTDECL(int) RTSemEventMultiWaitEx(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout)
315
#ifndef RTSEMEVENT_STRICT
316
return rtSemEventMultiWinWait(hEventMultiSem, fFlags, uTimeout, NULL);
318
RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API();
319
return rtSemEventMultiWinWait(hEventMultiSem, fFlags, uTimeout, &SrcPos);
324
RTDECL(int) RTSemEventMultiWaitExDebug(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout,
325
RTHCUINTPTR uId, RT_SRC_POS_DECL)
327
RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API();
328
return rtSemEventMultiWinWait(hEventMultiSem, fFlags, uTimeout, &SrcPos);
269
333
RTDECL(void) RTSemEventMultiSetSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread)