public bool WaitOne(int timeout) { QueueSync queueSync; lock (_mainSync) { if (_currentCount > 0) { _currentCount--; return(true); } else { queueSync = new QueueSync(); _queueSyncs.Enqueue(queueSync); } } lock (queueSync) { if (queueSync.IsSignaled || Monitor.Wait(queueSync, timeout)) { return(true); } else { queueSync.IsAbandoned = true; return(false); } } }
public void Release() { lock (_mainSync) { if (_currentCount >= _maximumCount) { throw new SemaphoreFullException(); } CheckQueue: if (_queueSyncs.Count == 0) { _currentCount++; } else { QueueSync queueSync = _queueSyncs.Dequeue(); lock (queueSync) { if (queueSync.IsAbandoned) { goto CheckQueue; } // Backup signal in case we acquired the lock before the waiter queueSync.IsSignaled = true; Monitor.Pulse(queueSync); } } } }
public void Release() { lock (_mainSync) { if (_currentCount >= _maximumCount) // Workaround for Mono { Type semaphoreException = Type.GetType("System.Threading.SemaphoreFullException"); object exception = Activator.CreateInstance(semaphoreException); throw (SystemException)exception; } CheckQueue: if (_queueSyncs.Count == 0) { _currentCount++; } else { QueueSync queueSync = _queueSyncs.Dequeue(); lock (queueSync) { if (queueSync.IsAbandoned) { goto CheckQueue; } // Backup signal in case we acquired the lock before the waiter queueSync.IsSignaled = true; Monitor.Pulse(queueSync); } } } }