/// <summary> /// Blocks if no release is signaled or removes a release signal. Enter a critical section. /// In theory, this method is often called P() [Dijkstra, dutch: passeeren] /// </summary> /// <remarks>This member is thread-safe.</remarks> public void Acquire() { while (true) { //looped 0.5s timeout to make blocked threads abortable. uint res = NTKernel.WaitForSingleObject(handle, interruptReactionTime); try { System.Threading.Thread.Sleep(0); } catch (System.Threading.ThreadInterruptedException e) { if (res == 0) { int previousCount; NTKernel.ReleaseSemaphore(handle, 1, out previousCount); } throw e; } if (res == 0) { return; } if (res != 258) { throw new SemaphoreFailedException(); } } }
/// <summary> /// Signals a release and allows a blocked thread to continue. Leave a critical section. /// In theory, this method is often called V() [Dijkstra, dutch: vrijgeven] /// </summary> /// <remarks>This member is thread-safe.</remarks> public void Release() { int previousCount; if (!NTKernel.ReleaseSemaphore(handle, 1, out previousCount)) { throw new SemaphoreFailedException(); } }