// // Tries to unregister the callback. This method is thread-safe. // public bool Unregister() { StParker p = parker; if (p == null) { return(false); } parker = null; if (p.TryCancel()) { p.Unpark(StParkStatus.WaitCancelled); return(true); } return(false); }
// // 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); }
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); }