public void Unpark(int status) { if (UnparkInProgress(status)) { return; } if (parkSpot != null) { parkSpot.Set(); } else { // // This is a callback parker. // If a timer was used and it didn't fire, unlink the timer // (whose parker is already locked) from the timer list. // Finally, execute the associated callback. // var cbpk = (CbParker)this; if (cbpk.toTimer != null && status != StParkStatus.Timeout) { TimerList.UnlinkRawTimer(cbpk.toTimer); cbpk.toTimer = null; } cbpk.callback(status); } }
// // Enables the unpark callback. // internal int EnableCallback(int timeout, RawTimer tmr) { // // If the unpark method was already called, return immediately. // if (state >= 0) { return(waitStatus); } toTimer = null; if (timeout == 0) { // // If a zero timeout is specified with a timer, we record the // current time as *fireTime* in order to support periodic timers. // if (tmr != null) { tmr.fireTime = Environment.TickCount; } if (TryCancel()) { return(StParkStatus.Timeout); } } else if (timeout != Timeout.Infinite) { toTimer = tmr; if (timeout < 0) { TimerList.SetPeriodicRawTimer(tmr, timeout & ~(1 << 31)); } else { TimerList.SetRawTimer(tmr, timeout); } } // // Clear the wait-in-progress bit. If this bit is already cleared, // the current thread was already unparked. // if (!TestAndClearInProgress()) { if (toTimer != null && waitStatus != StParkStatus.Timeout) { TimerList.UnlinkRawTimer(tmr); } return(waitStatus); } return(StParkStatus.Pending); }