public void AquireReleaseInSameThread() { Semaphore s = new Semaphore(1); s.Acquire(); s.Release(); s.Acquire(); s.Release(); s.Acquire(); s.Release(); s.Acquire(); s.Release(); s.Acquire(); s.Release(); s.Acquire(); s.Release(); Assert.AreEqual(1, s.Permits); }
/// <summary> /// The actual rendezvous logic for the given time /// </summary> protected internal virtual System.Object doRendezvous(System.Object x, bool timed, long msecs) { // rely on semaphore to throw interrupt on entry long startTime; if (timed) { startTime = Utils.CurrentTimeMillis; if (!entryGate_.Attempt(msecs)) { throw new TimeoutException(msecs); } } else { startTime = 0; entryGate_.Acquire(); } lock (this) { System.Object y = null; int index = entries_++; slots_[index] = x; try { // last one in runs function and releases if (entries_ == parties_) { departures_ = entries_; System.Threading.Monitor.PulseAll(this); try { if (!broken_ && rendezvousFunction_ != null) { rendezvousFunction_.RendezvousFunction(slots_); } } catch (System.SystemException) { broken_ = true; } } else { while (!broken_ && departures_ < 1) { long timeLeft = 0; if (timed) { timeLeft = msecs - (Utils.CurrentTimeMillis - startTime); if (timeLeft <= 0) { broken_ = true; departures_ = entries_; System.Threading.Monitor.PulseAll(this); throw new TimeoutException(msecs); } } try { System.Threading.Monitor.Wait(this, TimeSpan.FromMilliseconds(timeLeft)); } catch (System.Threading.ThreadInterruptedException ex) { if (broken_ || departures_ > 0) { // interrupted after release Thread.CurrentThread.Interrupt(); break; } else { broken_ = true; departures_ = entries_; System.Threading.Monitor.PulseAll(this); throw ex; } } } } } finally { y = slots_[index]; // Last one out cleans up and allows next set of threads in if (--departures_ <= 0) { for (int i = 0; i < slots_.Length; ++i) { slots_[i] = null; } entryGate_.Release(entries_); entries_ = 0; } } // continue if no IE/TO throw if (broken_) { throw new BrokenBarrierException(index); } else { return(y); } } }