// // 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); }
// // Signals the event. // internal override bool _Release() { return(tmrEvent._Release()); }