// Acquire the lock for read (shared) access public void LockRead() { lock (monitor) { // if there isn’t blocked writers and the resource isn’t being written, grant // read access immediately if (writeReqQueue.Count == 0 && state >= 0) { state++; // add one reader return; } // otherwise, enqueue a read access request LockReadRequest request = EnqueueReader(); // wait until request is granted, or the thread gives up due to interruption do { try { MonitorEx.Wait(monitor, monitor); // eq a Monitor.Wait(monitor); } catch (ThreadInterruptedException) { // if the requested shared access was granted, we must re-assert interrupt // exception, and return normally. if (request.done) { Thread.CurrentThread.Interrupt(); break; } // otherwise, we remove the request from the queue and re-throw the exception RemoveReader(); throw; } // if shared access was granted then return; otherwise, re-wait } while (!request.done); } }
/* * Methods that implement the lock read request queue */ private LockReadRequest EnqueueReader() { if (readReqQueue == null) { readReqQueue = new LockReadRequest(); } else { readReqQueue.waiters++; } return(readReqQueue); }
private void ClearReaderQueue() { readReqQueue = null; }