/// <summary> /// Creates new timers. This method is thread-safe. /// </summary> /// <param name="callback">The callback.</param> /// <param name="context">The context.</param> /// <returns><see cref="CancellationTimer" />Timer.</returns> public override CancellationTimer CreateTimer(Callback callback, object context) { var timer = new CountdownTimerNode(callback, context, this.Duration, this._countdownTimerNode); // Add this on the tail. (Actually, one before the tail - _timers is the sentinel tail.) var needProd = false; lock (this._countdownTimerNode) { // If this is the first timer in the list, we need to create a queue handle and prod the timer thread. if (this._countdownTimerNode.Next == this._countdownTimerNode) { if (this._thisHandle == IntPtr.Zero) { this._thisHandle = (IntPtr)GCHandle.Alloc(this); } needProd = true; } timer.Next = this._countdownTimerNode; timer.Prev = this._countdownTimerNode.Prev; this._countdownTimerNode.Prev.Next = timer; this._countdownTimerNode.Prev = timer; } // If, after we add the new tail, there is a chance that the tail is the next // node to be processed, we need to wake up the timer thread. if (needProd) { CountdownTimer.Prod(); } return(timer); }
/// <summary> /// Creates new timers. This method is thread-safe. /// </summary> /// <param name="callback">The callback.</param> /// <param name="context">The context.</param> /// <returns>CountdownTimerTimer.</returns> public override CancelationTimer CreateTimer(Callback callback, object context) { var timer = new CountdownTimerNode(callback, context, Duration, _timers); // Add this on the tail. (Actually, one before the tail - _timers is the sentinel tail.) var needProd = false; lock (_timers) { //if (!(_timers.Prev!.Next == _timers)) //{ // NetEventSource.Fail(this, $"Tail corruption."); //} // If this is the first timer in the list, we need to create a queue handle and prod the timer thread. if (_timers.Next == _timers) { if (_thisHandle == IntPtr.Zero) { _thisHandle = (IntPtr)GCHandle.Alloc(this); } needProd = true; } timer.Next = _timers; timer.Prev = _timers.Prev; _timers.Prev.Next = timer; _timers.Prev = timer; } // If, after we add the new tail, there is a chance that the tail is the next // node to be processed, we need to wake up the timer thread. if (needProd) { CountdownTimer.Prod(); } return(timer); }