void doReadThread (void* arg) { PRInt32 last; Arg_t *args = (Arg_t*)arg; PRInt32 aWorkDelay = args->a, aWaitDelay = args->b; PR_Sleep(0); while (1) { // -- enter read lock PR_EnterMonitor (gMonitor); if (0 < gWriteWaiting) // give up the monitor to waiting writes { PRIntervalTime fiveSecs = PR_SecondsToInterval(5); gReadWaiting++; if (gReadWaiting > gMaxReadWaits) // stats gMaxReadWaits = gReadWaiting; while (0 < gWriteWaiting) PR_Wait (gMonitor, fiveSecs); gReadWaiting--; } gReading++; gReads++; // stats if (gReading > gMaxReads) // stats gMaxReads = gReading; PR_ExitMonitor (gMonitor); // -- read lock entered last = gCounter; spin (aWorkDelay); PR_ASSERT (gCounter == last); // test invariance // -- exit read lock PR_EnterMonitor (gMonitor); // read unlock gReading--; // if ((0 == gReading) && (0 < gWriteWaiting)) // notify waiting writes (do it anyway to show off the CondWait bug) PR_NotifyAll (gMonitor); PR_ExitMonitor (gMonitor); // -- read lock exited spin (aWaitDelay); } }
void doWriteThread (void* arg) { PRInt32 last; Arg_t *args = (Arg_t*)arg; PRInt32 aWorkDelay = args->a, aWaitDelay = args->b; PR_Sleep(0); while (1) { // -- enter write lock PR_EnterMonitor (gMonitor); if (0 < gReading) // wait for read locks to go away { PRIntervalTime fiveSecs = PR_SecondsToInterval(5); gWriteWaiting++; if (gWriteWaiting > gMaxWriteWaits) // stats gMaxWriteWaits = gWriteWaiting; while (0 < gReading) PR_Wait (gMonitor, fiveSecs); gWriteWaiting--; } // -- write lock entered last = gCounter; gCounter++; spin (aWorkDelay); PR_ASSERT (gCounter == (last + 1)); // test invariance // -- exit write lock // if (0 < gReadWaiting) // notify waiting reads (do it anyway to show off the CondWait bug) PR_NotifyAll (gMonitor); PR_ExitMonitor (gMonitor); // -- write lock exited spin (aWaitDelay); } }
JD_METHOD_(JDBool) CNSAdapter_NSPR::JD_NotifyAll(void* mon) { return PR_NotifyAll((PRMonitor*)mon); }