Example #1
0
        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);
        }
Example #2
0
        /// <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);
                }
            }
        }