Changeset 2209


Ignore:
Timestamp:
Jul 4, 2017, 5:00:23 PM (8 years ago)
Author:
dmik
Message:

nspr: Use PM-friendly WinWaitEventSem and WinRequestMutexSem.

This avoids PM deadlocks when NSPR blocking functions are used
on a GUI thread processing PM messages. Closes #166.

Location:
nspr/trunk/pr
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified nspr/trunk/pr/include/md/_os2.h

    r2186 r2209  
    303303#define _MD_NEW_LOCK                  (_PR_MD_NEW_LOCK)
    304304#define _MD_FREE_LOCK(lock)           (DosCloseMutexSem((lock)->mutex))
    305 #define _MD_LOCK(lock)                (DosRequestMutexSem((lock)->mutex, SEM_INDEFINITE_WAIT))
    306 #define _MD_TEST_AND_LOCK(lock)       (DosRequestMutexSem((lock)->mutex, SEM_INDEFINITE_WAIT),0)
     305#define _MD_LOCK(lock)                (SafeRequestMutexSem((lock)->mutex, SEM_INDEFINITE_WAIT))
     306#define _MD_TEST_AND_LOCK(lock)       (SafeRequestMutexSem((lock)->mutex, SEM_INDEFINITE_WAIT),0)
    307307#define _MD_UNLOCK                    (_PR_MD_UNLOCK)
    308308
     
    488488
    489489extern APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD);
     490extern ULONG (* APIENTRY SafeWaitEventSem)(HEV hev, ULONG ulTimeout);
     491extern ULONG (* APIENTRY SafeRequestMutexSem)(HMTX hmtx, ULONG ulTimeout);
    490492
    491493/*
  • TabularUnified nspr/trunk/pr/src/md/os2/os2cv.c

    r1488 r2209  
    246246
    247247    /* Wait for notification or timeout; don't really care which */
    248     rv = DosWaitEventSem(thred->md.blocked_sema, msecs);
     248    rv = SafeWaitEventSem(thred->md.blocked_sema, msecs);
    249249    if (rv == NO_ERROR) {
    250250        DosResetEventSem(thred->md.blocked_sema, &count);
    251251    }
    252252
    253     DosRequestMutexSem((lock->mutex), SEM_INDEFINITE_WAIT);
     253    SafeRequestMutexSem((lock->mutex), SEM_INDEFINITE_WAIT);
    254254
    255255    PR_ASSERT(rv == NO_ERROR || rv == ERROR_TIMEOUT);
     
    287287            * non-signaled.  We assume this wait won't take long.
    288288            */
    289            rv = DosWaitEventSem(thred->md.blocked_sema, SEM_INDEFINITE_WAIT);
     289           rv = SafeWaitEventSem(thred->md.blocked_sema, SEM_INDEFINITE_WAIT);
    290290           if (rv == NO_ERROR) {
    291291               DosResetEventSem(thred->md.blocked_sema, &count);
  • TabularUnified nspr/trunk/pr/src/md/os2/os2io.c

    r2187 r2209  
    3434    PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ?
    3535        SEM_INDEFINITE_WAIT : PR_IntervalToMilliseconds(ticks);
    36     rv = DosWaitEventSem(thread->md.blocked_sema, msecs);
     36    rv = SafeWaitEventSem(thread->md.blocked_sema, msecs);
    3737    DosResetEventSem(thread->md.blocked_sema, &count);
    3838    switch(rv)
     
    5555                     */
    5656                    _PR_THREAD_UNLOCK(thread);
    57                     rv = DosWaitEventSem(thread->md.blocked_sema, 0);
     57                    rv = SafeWaitEventSem(thread->md.blocked_sema, 0);
    5858                    DosResetEventSem(thread->md.blocked_sema, &count);
    5959                    PR_ASSERT(rv == NO_ERROR);
  • TabularUnified nspr/trunk/pr/src/md/os2/os2sem.c

    r1488 r2209  
    3737{
    3838    int rv;
    39     rv = DosWaitEventSem(md->sem, PR_IntervalToMilliseconds(ticks));
     39    rv = SafeWaitEventSem(md->sem, PR_IntervalToMilliseconds(ticks));
    4040
    4141    if (rv == NO_ERROR)
  • TabularUnified nspr/trunk/pr/src/md/os2/os2thred.c

    r2189 r2209  
    1212_NSPR_TLS*        pThreadLocalStorage = 0;
    1313_PRInterruptTable             _pr_interruptTable[] = { { 0 } };
    14 APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD);
     14APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD) = NULL;
     15ULONG (* APIENTRY SafeWaitEventSem)(HEV hev, ULONG ulTimeout) = DosWaitEventSem;
     16ULONG (* APIENTRY SafeRequestMutexSem)(HMTX hmtx, ULONG ulTimeout) = DosRequestMutexSem;
    1517
    1618void
     
    3133_PR_MD_EARLY_INIT()
    3234{
    33    HMODULE hmod;
    34 
    35    if (DosLoadModule(NULL, 0, "DOSCALL1", &hmod) == 0)
    36        DosQueryProcAddr(hmod, 877, "DOSQUERYTHREADCONTEXT",
    37                         (PFN *)&QueryThreadContext);
     35    HMODULE hmod;
     36
     37    /*
     38     * TODO QueryThreadContext usage is SERIOUSLY broken because:
     39     * - QueryThreadContext will remain unitialized if missing in DOSCALL1;
     40     * - a call to QueryThreadContext in os2gc.c incorrectly treats its return
     41     *   value as BOOL.
     42     */
     43    if (DosLoadModule(NULL, 0, "DOSCALL1", &hmod) == NO_ERROR)
     44        DosQueryProcAddr(hmod, 877, "DOSQUERYTHREADCONTEXT",
     45                         (PFN *)&QueryThreadContext);
     46
     47    /*
     48     * Use PM-friendly variants for DosWaitEventSem and DosRequestMutexSem when
     49     * they are available. This avoids blocking the entire PM when NSPR blocking
     50     * APIs are called on a GUI thread that is supposed to process all incoming
     51     * PM messages.
     52     */
     53
     54    if (DosLoadModule(NULL, 0, "PMWIN", &hmod) == NO_ERROR) {
     55        DosQueryProcAddr(hmod, 978, "WINWAITEVENTSEM",
     56                             (PFN *)&SafeWaitEventSem);
     57    }
     58
     59    if (DosLoadModule(NULL, 0, "PMWIN", &hmod) == NO_ERROR) {
     60        DosQueryProcAddr(hmod, 979, "WINREQUESTMUTEXSEM",
     61                             (PFN *)&SafeRequestMutexSem);
     62    }
    3863}
    3964
Note: See TracChangeset for help on using the changeset viewer.