~ubuntu-branches/ubuntu/raring/virtualbox-ose/raring

« back to all changes in this revision

Viewing changes to src/VBox/Runtime/r3/win/semeventmulti-win.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2011-01-30 23:27:25 UTC
  • mfrom: (0.3.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20110130232725-2ouajjd2ggdet0zd
Tags: 4.0.2-dfsg-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - Add Apport hook.
    - debian/virtualbox-ose.files/source_virtualbox-ose.py
    - debian/virtualbox-ose.install
  - Drop *-source packages.
* Drop ubuntu-01-fix-build-gcc45.patch, fixed upstream.
* Drop ubuntu-02-as-needed.patch, added to the Debian package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: semeventmulti-win.cpp $ */
 
1
/* $Id: semeventmulti-win.cpp 32970 2010-10-07 10:08:00Z vboxsync $ */
2
2
/** @file
3
3
 * IPRT - Multiple Release Event Semaphore, Windows.
4
4
 *
43
43
#include <iprt/lockvalidator.h>
44
44
#include <iprt/mem.h>
45
45
#include <iprt/thread.h>
 
46
#include <iprt/time.h>
46
47
#include "internal/magics.h"
47
48
#include "internal/strict.h"
48
49
 
201
202
 
202
203
 
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)
205
207
{
206
208
    switch (rc)
207
209
    {
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;
212
214
        default:
213
215
            AssertMsgFailed(("%u\n", rc));
225
227
}
226
228
 
227
229
 
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)
230
232
{
231
 
    PCRTLOCKVALSRCPOS pSrcPos = NULL;
232
 
 
233
233
    /*
234
234
     * Validate input.
235
235
     */
236
236
    struct RTSEMEVENTMULTIINTERNAL *pThis = hEventMultiSem;
237
237
    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
238
238
    AssertReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, VERR_INVALID_HANDLE);
239
 
 
240
 
    /*
241
 
     * Wait for condition.
242
 
     */
 
239
    AssertReturn(RTSEMWAIT_FLAGS_ARE_VALID(fFlags), VERR_INVALID_PARAMETER);
 
240
 
 
241
    /*
 
242
     * Convert the timeout to a millisecond count.
 
243
     */
 
244
    uint64_t uAbsDeadline;
 
245
    DWORD    dwMsTimeout;
 
246
    if (fFlags & RTSEMWAIT_FLAGS_INDEFINITE)
 
247
    {
 
248
        dwMsTimeout  = INFINITE;
 
249
        uAbsDeadline = UINT64_MAX;
 
250
    }
 
251
    else
 
252
    {
 
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)
 
258
        {
 
259
            uAbsDeadline = uTimeout;
 
260
            uint64_t u64Now = RTTimeSystemMilliTS();
 
261
            if (u64Now < uTimeout)
 
262
                uTimeout -= u64Now;
 
263
            else
 
264
                uTimeout = 0;
 
265
        }
 
266
        else if (fFlags & RTSEMWAIT_FLAGS_RESUME)
 
267
            uAbsDeadline = RTTimeSystemMilliTS() + uTimeout;
 
268
        else
 
269
            uAbsDeadline = UINT64_MAX;
 
270
 
 
271
        dwMsTimeout = uTimeout < UINT32_MAX
 
272
                    ? (DWORD)uTimeout
 
273
                    : INFINITE;
 
274
    }
 
275
 
 
276
    /*
 
277
     * Do the wait.
 
278
     */
 
279
    DWORD rc;
243
280
#ifdef RTSEMEVENT_STRICT
244
281
    RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
245
282
    if (pThis->fEverHadSignallers)
246
283
    {
247
 
        DWORD rc = WaitForSingleObjectEx(pThis->hev,
248
 
                                         0 /*Timeout*/,
249
 
                                         TRUE /*fAlertable*/);
250
 
        if (rc != WAIT_TIMEOUT || cMillies == 0)
251
 
            return rtSemEventWaitHandleStatus(pThis, rc);
 
284
        do
 
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))
255
292
            return rc9;
256
293
    }
258
295
    RTTHREAD hThreadSelf = RTThreadSelf();
259
296
#endif
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))
 
300
    {
 
301
        while (   rc == WAIT_IO_COMPLETION
 
302
               && RTTimeSystemMilliTS() < uAbsDeadline)
 
303
            rc = WaitForSingleObjectEx(pThis->hev, dwMsTimeout, TRUE /*fAlertable*/);
 
304
 
 
305
    }
264
306
    RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT_MULTI);
265
 
    return rtSemEventWaitHandleStatus(pThis, rc);
266
 
}
 
307
    return rtSemEventWaitHandleStatus(pThis, fFlags, rc);
 
308
}
 
309
 
 
310
 
 
311
 
 
312
#undef RTSemEventMultiWaitEx
 
313
RTDECL(int)  RTSemEventMultiWaitEx(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout)
 
314
{
 
315
#ifndef RTSEMEVENT_STRICT
 
316
    return rtSemEventMultiWinWait(hEventMultiSem, fFlags, uTimeout, NULL);
 
317
#else
 
318
    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API();
 
319
    return rtSemEventMultiWinWait(hEventMultiSem, fFlags, uTimeout, &SrcPos);
 
320
#endif
 
321
}
 
322
 
 
323
 
 
324
RTDECL(int)  RTSemEventMultiWaitExDebug(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout,
 
325
                                        RTHCUINTPTR uId, RT_SRC_POS_DECL)
 
326
{
 
327
    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API();
 
328
    return rtSemEventMultiWinWait(hEventMultiSem, fFlags, uTimeout, &SrcPos);
 
329
}
 
330
 
267
331
 
268
332
 
269
333
RTDECL(void) RTSemEventMultiSetSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread)