Internal mechanism used when timers are added to wake up / create the thread.
internal override TimerThread.Timer CreateTimer(TimerThread.Callback callback, object context) { TimerThread.TimerNode node = new TimerThread.TimerNode(callback, context, base.Duration, this.m_Timers); bool flag = false; lock (this.m_Timers) { if (this.m_Timers.Next == this.m_Timers) { if (this.m_ThisHandle == IntPtr.Zero) { this.m_ThisHandle = (IntPtr)GCHandle.Alloc(this); } flag = true; } node.Next = this.m_Timers; node.Prev = this.m_Timers.Prev; this.m_Timers.Prev.Next = node; this.m_Timers.Prev = node; } if (flag) { TimerThread.Prod(); } return(node); }
/// <summary> /// <para>Creates new timers. This method is thread-safe.</para> /// </summary> internal override Timer CreateTimer(Callback callback, object context) { TimerNode timer = new TimerNode(callback, context, Duration, _timers); // Add this on the tail. (Actually, one before the tail - _timers is the sentinel tail.) bool needProd = false; lock (_timers) { if (!(_timers.Prev.Next == _timers)) { if (GlobalLog.IsEnabled) { GlobalLog.AssertFormat("TimerThread#{0}::CreateTimer()|Tail corruption.", Thread.CurrentThread.ManagedThreadId.ToString()); } Debug.Fail(string.Format("TimerThread#{0}::CreateTimer()|Tail corruption.", Thread.CurrentThread.ManagedThreadId.ToString())); } // 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) { TimerThread.Prod(); } return(timer); }
/// <summary> /// <para>Creates new timers. This method is thread-safe.</para> /// </summary> internal override Timer CreateTimer(Callback callback, object context) { TimerNode timer = new TimerNode(callback, context, Duration, _timers); // Add this on the tail. (Actually, one before the tail - _timers is the sentinel tail.) bool 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) { TimerThread.Prod(); } return(timer); }