/// <summary> /// Unlock function. Removes Synchronizer lock so that pending operation waiting to get a lock on the Synchronizer, will be able to get one. /// </summary> public void Unlock() { if (((CurrentOperation == OperationType.Read || CurrentOperation == OperationType.Search) && Interlocked.Decrement(ref ReadCount) == 0) || CurrentOperation == OperationType.Write) { CurrentOperation = OperationType.Idle; SingleThreadAccess.Unlock(this); return; } }
// Logic table: //Current Operation : Requested Operation : Result //Idle : Read/Search or Write : Allowed //Read/Search : Read/Search : Allowed //Read/Search : Write : Wait until Read/Search is done //Write : Read/Search or Write : Wait until Write is done // /// <summary> /// Locks this Synchronizer so that other threads won't be able to access this Synchronizer until this Synchronizer gets Unlocked. See Unlock function below. /// </summary> /// <param name="RequestedOperation">Lock resource for Read, Write or Search</param> public void Lock(OperationType RequestedOperation) { if (!IsWriteRequested && (CurrentOperation == OperationType.Read || CurrentOperation == OperationType.Search) && (RequestedOperation == OperationType.Read || RequestedOperation == OperationType.Search)) { // we don't need to lock since reading could be done by more than one thread. As result, multiple reads invoked by multiple threads will run in parallel! Interlocked.Increment(ref ReadCount); } else { if (!IsWriteRequested) { IsWriteRequested = (CurrentOperation == OperationType.Read || CurrentOperation == OperationType.Search) && RequestedOperation == OperationType.Write; } SingleThreadAccess.Lock(this); IsWriteRequested = false; CurrentOperation = RequestedOperation; if (RequestedOperation == OperationType.Read || RequestedOperation == OperationType.Search) { ReadCount = 1; } } }