//
        // Signals a waitable and waits on another as an atomic
        // operation, activating the specified cancellers.
        //

        public static bool SignalAndWait(StWaitable tos, StWaitable tow, StCancelArgs cargs)
        {
            //
            // Create a parker to execute the WaitAny prologue on the
            // *tow* waitable.
            //

            StParker  pk   = new StParker();
            WaitBlock hint = null;
            int       sc   = 0;
            WaitBlock wb   = tow._WaitAnyPrologue(pk, StParkStatus.Success, ref hint, ref sc);

            //
            // Signal the *tos* waitable.
            //

            if (!tos._Release())
            {
                //
                // The signal operation failed. So, try to cancel the parker and,
                // if successful, cancel the acquire attempt; otherwise, wait until
                // the thread is unparked and, then, undo the acquire.
                //

                if (pk.TryCancel())
                {
                    tow._CancelAcquire(wb, hint);
                }
                else
                {
                    pk.Park();
                    tow._UndoAcquire();
                }

                //
                // Report the failure appropriately.
                //

                throw tos._SignalException;
            }

            //
            // Park the current thread, activating the specified cancellers
            // and spinning if appropriate.
            //

            int ws = pk.Park(sc, cargs);

            //
            // If we acquired, execute the WaitOne epilogue and return success.
            //

            if (ws == StParkStatus.Success)
            {
                tow._WaitEpilogue();
                return(true);
            }

            //
            // The acquire operation was cancelled; so, cancel the acquire
            // attempt and report the failure appropriately.
            //

            tow._CancelAcquire(wb, hint);
            StCancelArgs.ThrowIfException(ws);
            return(false);
        }
示例#2
0
        //
        // Signals the event.
        //

        internal override bool _Release()
        {
            return(tmrEvent._Release());
        }