Ejemplo n.º 1
0
        public void Wait(StParker pk, StCancelArgs cargs)
        {
            bool interrupted = false;
            int  lastTime    = (cargs.Timeout != Timeout.Infinite) ? Environment.TickCount : 0;
            int  ws;

            do
            {
                try {
                    ws = waitBehavior.Park(psevent, cargs.Timeout);
                    break;
                } catch (ThreadInterruptedException) {
                    if (cargs.Interruptible)
                    {
                        ws = StParkStatus.Interrupted;
                        break;
                    }
                    interrupted = true;
                    cargs.AdjustTimeout(ref lastTime);
                }
            } while (true);

            //
            // If the wait was cancelled due to an internal canceller, try
            // to cancel the park operation. If we fail, wait unconditionally
            // until the park spot is signalled.
            //

            if (ws != StParkStatus.Success)
            {
                if (pk.TryCancel())
                {
                    pk.UnparkSelf(waitBehavior.ParkerCancelled(ws));
                }
                else
                {
                    if (ws == StParkStatus.Interrupted)
                    {
                        interrupted = true;
                    }

                    waitBehavior.ParkerNotCancelled(ws);

                    do
                    {
                        try {
                            psevent.WaitOne();
                            break;
                        } catch (ThreadInterruptedException) {
                            interrupted = true;
                        }
                    } while (true);
                }
            }

            //
            // If we were interrupted but can't return the *interrupted*
            // wait status, reassert the interrupt on the current thread.
            //

            if (interrupted)
            {
                Thread.CurrentThread.Interrupt();
            }

            factory.Free(this);
        }