// // Spins until the specified condition is true. // internal static void SpinUntil(Func<bool> condition) { if (condition == null) { throw new ArgumentNullException("condition"); } StSpinWait spinner = new StSpinWait(); while (!condition()) { spinner.SpinOnce(); } }
// // Spins until the specified condition is true. // internal static void SpinUntil(Func <bool> condition) { if (condition == null) { throw new ArgumentNullException("condition"); } StSpinWait spinner = new StSpinWait(); while (!condition()) { spinner.SpinOnce(); } }
// // Unregisters the registered wait. // public bool Unregister() { // // If the unregister is being called from the callback method, // we just set the *onlyOnce* to TRUE and return. // if (cbtid == Thread.CurrentThread.ManagedThreadId) { executeOnce = true; return true; } // // If the wait is registered, we try to unregister it, and return // only after the wait is actually unregistered. // If the wait was already unregistered or an unregister is taking // place, this method returns false. // StSpinWait spinner = new StSpinWait(); StParker pk = new StParker(0); StParker oldState; do { if ((oldState = state) == INACTIVE) { return false; } if (oldState == ACTIVE) { if (Interlocked.CompareExchange<StParker>(ref state, pk, ACTIVE) == ACTIVE) { break; } } else if (!(oldState is SentinelParker)) { return false; } spinner.SpinOnce(); } while (true); // // Try to cancel the wait's callback parker. If we succeed, call // the unpark with status disposed. Otherwise, a callback is taking // place and we must synchronize with its end. // if (cbparker.TryCancel()) { cbparker.Unpark(StParkStatus.WaitCancelled); } else { pk.Park(BUSY_SPINS, StCancelArgs.None); } // // Set the registered wait object to inactive and return success. // state = INACTIVE; return true; }
// // Unregisters the registered take. // public bool Unregister() { // // If the unregister is being called from the callback method, // we just set the *onlyOnce* to *true* and return. // if (cbtid == Thread.CurrentThread.ManagedThreadId) { executeOnce = true; return(true); } // // If the take is registered, we try to unregister it, and return // only after the wait is actually unregistered. // If the take was already unregistered or an unregister is taking // place, this method returns false. // StSpinWait spinner = new StSpinWait(); StParker pk = new StParker(0); StParker oldState; do { if ((oldState = state) == INACTIVE) { return(false); } if (oldState == ACTIVE) { if (Interlocked.CompareExchange <StParker>(ref state, pk, ACTIVE) == ACTIVE) { break; } } else if (!(oldState is SentinelParker)) { return(false); } spinner.SpinOnce(); } while (true); // // Try to cancel the callback parker. If we succeed, call the unpark // with status cancelled. Otherwise, a callback is taking place and // we must wait until its completion. // if (cbparker.TryCancel()) { cbparker.Unpark(StParkStatus.TakeCancelled); } else { pk.Park(BUSY_SPINS, StCancelArgs.None); } // // Set the registered take object to inactive and return success. // state = INACTIVE; return(true); }
// // Cancels the timer. // public bool Cancel() { // // If the timer is being cancelled from the user callback function, // set the period to zero and return success. The timer will be // cancelled on return from the callback function. // if (cbtid == Thread.CurrentThread.ManagedThreadId) { period = 0; return true; } // // If the timer is active we must try to cancel the timer // and return only after the timer is actually cancelled. // if the timer is already inactive or a cancel or a set is taking // place, this function returns FALSE. // StSpinWait spinner = new StSpinWait(); StParker pk = new StParker(0); StParker oldState; do { if ((oldState = state) == INACTIVE) { return false; } if (oldState == ACTIVE) { if (Interlocked.CompareExchange<StParker>(ref state, pk, ACTIVE) == ACTIVE) { break; } } if (!(oldState is SentinelParker)) { return false; } spinner.SpinOnce(); } while (true); // // Try to cancel the timer's callback parker. If we can't // park the current thread until the timer callback finishes // execution. // if (cbparker.TryCancel()) { cbparker.Unpark(StParkStatus.TimerCancelled); } else { pk.Park(100, StCancelArgs.None); } // // Set the timer state to inactive and return success. // state = INACTIVE; return true; }
// // Sets the timer. // public bool Set(int dueTime, int period, WaitOrTimerCallback callback, object cbState) { // // If the timer is being set from the user callback function, // we just save the new settings and return success. // if (cbtid == Thread.CurrentThread.ManagedThreadId) { this.dueTime = dueTime; this.period = period; useDueTime = true; this.callback = callback; this.cbState = cbState; return true; } // // The timer is being set externally. So, we must first cancel the // timer. If the timer is already being set or cancelled, we return // failure. // StSpinWait spinner = new StSpinWait(); StParker pk = new StParker(0); StParker oldState; do { if ((oldState = state) == INACTIVE) { if (Interlocked.CompareExchange<StParker>(ref state, SETTING, INACTIVE) == INACTIVE) { goto SetTimer; } } else if (oldState == ACTIVE) { if (Interlocked.CompareExchange<StParker>(ref state, pk, ACTIVE) == ACTIVE) { break; } } else if (!(oldState is SentinelParker)) { return false; } spinner.SpinOnce(); } while (true); // // Try to cancel the timer's callback parker. If succeed, // call the unpark method; otherwise, the timer callback is // taking place, so we must synchronize with its end. // if (cbparker.TryCancel()) { cbparker.Unpark(StParkStatus.TimerCancelled); } else { pk.Park(100, StCancelArgs.None); } // // Here, we know that the timer is cancelled and no one else // is trying to set or cancel the timer. // So, set the timer state to *our busy state* and start it with // the new settings. // state = SETTING; SetTimer: this.dueTime = dueTime; this.period = period; useDueTime = false; this.callback = callback; this.cbState = cbState; StNotificationEvent nev = tmrEvent as StNotificationEvent; if (nev != null) { nev.Reset(); } else { ((StSynchronizationEvent)tmrEvent).Reset(); } // // Initialize the timer's parker, set the timer state to ACTIVE // and enable the unpark callback. // cbparker.Reset(); state = ACTIVE; int ws = cbparker.EnableCallback(dueTime, timer); if (ws != StParkStatus.Pending) { // // If the timer already fired or cancelled, call the unpark // callback inline. // TimerCallback(ws); } return true; }
// // Cancels the timer. // public bool Cancel() { // // If the timer is being cancelled from the user callback function, // set the period to zero and return success. The timer will be // cancelled on return from the callback function. // if (cbtid == Thread.CurrentThread.ManagedThreadId) { period = 0; return(true); } // // If the timer is active we must try to cancel the timer // and return only after the timer is actually cancelled. // if the timer is already inactive or a cancel or a set is taking // place, this function returns FALSE. // StSpinWait spinner = new StSpinWait(); StParker pk = new StParker(0); StParker oldState; do { if ((oldState = state) == INACTIVE) { return(false); } if (oldState == ACTIVE) { if (Interlocked.CompareExchange <StParker>(ref state, pk, ACTIVE) == ACTIVE) { break; } } if (!(oldState is SentinelParker)) { return(false); } spinner.SpinOnce(); } while (true); // // Try to cancel the timer's callback parker. If we can't // park the current thread until the timer callback finishes // execution. // if (cbparker.TryCancel()) { cbparker.Unpark(StParkStatus.TimerCancelled); } else { pk.Park(100, StCancelArgs.None); } // // Set the timer state to inactive and return success. // state = INACTIVE; return(true); }
// // Sets the timer. // public bool Set(int dueTime, int period, WaitOrTimerCallback callback, object cbState) { // // If the timer is being set from the user callback function, // we just save the new settings and return success. // if (cbtid == Thread.CurrentThread.ManagedThreadId) { this.dueTime = dueTime; this.period = period; useDueTime = true; this.callback = callback; this.cbState = cbState; return(true); } // // The timer is being set externally. So, we must first cancel the // timer. If the timer is already being set or cancelled, we return // failure. // StSpinWait spinner = new StSpinWait(); StParker pk = new StParker(0); StParker oldState; do { if ((oldState = state) == INACTIVE) { if (Interlocked.CompareExchange <StParker>(ref state, SETTING, INACTIVE) == INACTIVE) { goto SetTimer; } } else if (oldState == ACTIVE) { if (Interlocked.CompareExchange <StParker>(ref state, pk, ACTIVE) == ACTIVE) { break; } } else if (!(oldState is SentinelParker)) { return(false); } spinner.SpinOnce(); } while (true); // // Try to cancel the timer's callback parker. If succeed, // call the unpark method; otherwise, the timer callback is // taking place, so we must synchronize with its end. // if (cbparker.TryCancel()) { cbparker.Unpark(StParkStatus.TimerCancelled); } else { pk.Park(100, StCancelArgs.None); } // // Here, we know that the timer is cancelled and no one else // is trying to set or cancel the timer. // So, set the timer state to *our busy state* and start it with // the new settings. // state = SETTING; SetTimer: this.dueTime = dueTime; this.period = period; useDueTime = false; this.callback = callback; this.cbState = cbState; StNotificationEvent nev = tmrEvent as StNotificationEvent; if (nev != null) { nev.Reset(); } else { ((StSynchronizationEvent)tmrEvent).Reset(); } // // Initialize the timer's parker, set the timer state to ACTIVE // and enable the unpark callback. // cbparker.Reset(); state = ACTIVE; int ws = cbparker.EnableCallback(dueTime, timer); if (ws != StParkStatus.Pending) { // // If the timer already fired or cancelled, call the unpark // callback inline. // TimerCallback(ws); } return(true); }