// // Tries to wakeup a waiting upgrader and/or all the waiting readers. // private bool TryWakeupUpgraderAndReaders() { // // Initialize the wakeup list and the released flag. // WaitNodeQueue wl = new WaitNodeQueue(); bool released = false; // // If the upgraders wait queue isn't empty, try to wakeup a // waiting upgrader to enter the lock in upgradeable read mode. // if (!upQueue.IsEmpty) { do { WaitNode w = upQueue.Dequeue(); if (w.TryLock()) { // // Make the locked waiter as the current upgrader and // add its wait node to the wake up list. // upgrader = w.tid; wl.AddToWakeList(w); released = true; break; } } while (!upQueue.IsEmpty); } // // Even when the r/w lock state changes to the upgrade read mode, // all the waiting readers can enter the read lock. // while (!rdQueue.IsEmpty) { WaitNode w = rdQueue.Dequeue(); if (w.TryLock()) { // // Account for one more active reader, add the respective // entry to the reader owners table and add the waiting reader // to the wake up list. // readers++; rdCounts.Add(w.tid); wl.AddToWakeList(w); released = true; } } // // If no thread was released, return false holding the // spinlock; otherwise, release the spinlock, unpark all // threads inserted in the wake up list and return true. // if (!released) { return false; } slock.Exit(); wl.UnparkAll(); return true; }
// // Tries to wakeup a waiting upgrader and/or all the waiting readers. // private bool TryWakeupUpgraderAndReaders() { // // Initialize the wakeup list and the released flag. // WaitNodeQueue wl = new WaitNodeQueue(); bool released = false; // // If the upgraders wait queue isn't empty, try to wakeup a // waiting upgrader to enter the lock in upgradeable read mode. // if (!upQueue.IsEmpty) { do { WaitNode w = upQueue.Dequeue(); if (w.TryLock()) { // // Make the locked waiter as the current upgrader and // add its wait node to the wake up list. // upgrader = w.tid; wl.AddToWakeList(w); released = true; break; } } while (!upQueue.IsEmpty); } // // Even when the r/w lock state changes to the upgrade read mode, // all the waiting readers can enter the read lock. // while (!rdQueue.IsEmpty) { WaitNode w = rdQueue.Dequeue(); if (w.TryLock()) { // // Account for one more active reader, add the respective // entry to the reader owners table and add the waiting reader // to the wake up list. // readers++; rdCounts.Add(w.tid); wl.AddToWakeList(w); released = true; } } // // If no thread was released, return false holding the // spinlock; otherwise, release the spinlock, unpark all // threads inserted in the wake up list and return true. // if (!released) { return(false); } slock.Exit(); wl.UnparkAll(); return(true); }