예제 #1
0
        public override void Run()
        {
            Debug.Assert(_backgroundThread == null, "A thread is already running " + _backgroundThread);
            _backgroundThread = Thread.CurrentThread;
            _startupLatch.release();

            try
            {
                do
                {
                    AsyncEvent events = _stackUpdater.getAndSet(this, _endSentinel);
                    Process(events);
                    if (_stack == _endSentinel && !_shutdown)
                    {
                        LockSupport.park(this);
                    }
                } while (!_shutdown);

                AsyncEvent events = _stackUpdater.getAndSet(this, _shutdownSentinel);
                Process(events);
            }
            finally
            {
                _backgroundThread = null;
                _shutdownLatch.release();
            }
        }
예제 #2
0
 /// <summary>
 /// 线程休眠且检查是否被中断唤醒 这儿可能有问题!!!!!
 /// </summary>
 /// <returns></returns>
 private bool parkAndCheckInterrupt()
 {
     try
     {
         LockSupport.park(this);
         return(true);
     }
     catch (ThreadInterruptedException e)
     {
         return(false);
     }
 }
예제 #3
0
        /// <summary>
        /// 结束运行 依次唤醒等待get结果的节点 带超时机制
        /// </summary>
        /// <param name="timed"></param>
        /// <param name="nanos"></param>
        /// <returns></returns>
        private int awaitDone(bool timed, long nanos)
        {
            long     deadline = timed ? DateTime.Now.Ticks + nanos : 0L;
            WaitNode q        = null;
            bool     queued   = false;

            for (; ;)
            {
                //if (Thread.interrupted()) {
                //    removeWaiter(q);
                //    throw new ThreadInterruptedException();
                //}
                int s = state;
                if (s > COMPLETING)
                {
                    if (q != null)
                    {
                        q.thread = null;
                    }
                    return(s);
                }
                else if (s == COMPLETING)// cannot time out yet
                {
                    Thread.Yield();
                }
                else if (q == null)
                {
                    q = new WaitNode();
                }
                else if (!queued)
                {
                    queued = Interlocked.CompareExchange <WaitNode>(ref waiters, q, q.next = waiters) == q.next;
                }
                else if (timed)
                {
                    nanos = deadline - DateTime.Now.Ticks;
                    if (nanos <= 0L)
                    {
                        removeWaiter(q);
                        return(state);
                    }
                    LockSupport.parkNanos(this, nanos);
                }
                else
                {
                    LockSupport.park(this);
                }
            }
        }
예제 #4
0
            private void refill()
            {
                int count = 200;

                while (fillBacklog() == false)
                {
                    if (count > 100)
                    {
                        ;
                    }
                    else if (count > 0)
                    {
                        Thread.yield();
                    }
                    else
                    {
                        LockSupport.park();
                    }
                    count = count - 1;
                }
            }
예제 #5
0
        /// <summary>
        /// Wait for the latch to be released, blocking the current thread if necessary.
        /// <para>
        /// This method returns immediately if the latch has already been released.
        /// </para>
        /// </summary>
        public virtual void Await()
        {
            // Put in a local variable to avoid volatile reads we don't need.
            Node state = _stack;

            if (state != _released)
            {
                // The latch hasn't obviously already been released, so we want to add a waiter to the stack. Trouble is,
                // we might race with release here, so we need to re-check for release after we've modified the stack.
                Waiter waiter = new Waiter();
                state = ( Node )UnsafeUtil.getAndSetObject(this, _stackOffset, waiter);
                if (state == _released)
                {
                    // If we get 'released' back from the swap, then we raced with release, and it is our job to put the
                    // released sentinel back. Doing so can, however, return more waiters that have added themselves in
                    // the mean time. If we find such waiters, then we must make sure to unpark them. Note that we will
                    // never get a null back from this swap, because we at least added our own waiter earlier.
                    Node others = ( Node )UnsafeUtil.getAndSetObject(this, _stackOffset, _released);
                    // Set our next pointer to 'released' as a signal to other threads who might be going through the
                    // stack in the isReleased check.
                    waiter.Next = _released;
                    UnparkAll(others);
                }
                else
                {
                    // It looks like the latch hasn't yet been released, so we are going to park. Before that, we must
                    // assign a non-null value to our next pointer, so other threads will know that we have been properly
                    // enqueued. We use the 'end' sentinel as a marker when there's otherwise no other next node.
                    waiter.Next = state == null ? _end : state;
                    do
                    {
                        // Park may wake up spuriously, so we have to loop on it until we observe from the state of the
                        // stack, that the latch has been released.
                        LockSupport.park(this);
                    } while (!IsReleased(waiter));
                }
            }
        }