private static void Enqueue(LinkedList <IBlockingQueueServerWorker> inThreadPoolQueue, IBlockingQueueServerWorker inWorker) { if (inWorker == null) { // This is a shutdown signal, put at very front of queue inThreadPoolQueue.AddFirst(inWorker); } else if (inWorker.IsHighPriority) { LinkedListNode <IBlockingQueueServerWorker> currentNode = inThreadPoolQueue.First; while (currentNode != null) { if (currentNode.Value != null) { if (!currentNode.Value.IsHighPriority) { inThreadPoolQueue.AddBefore(currentNode, inWorker); return; } } currentNode = currentNode.Next; } inThreadPoolQueue.AddLast(inWorker); } else { inThreadPoolQueue.AddLast(inWorker); } }
public void Enqueue(IBlockingQueueServerWorker inWorker) { lock (m_LockObject) { DebugUtils.AssertDebuggerBreak(m_ThreadPoolQueue != null); DebugUtils.AssertDebuggerBreak(m_ShutdownAutoResetEvent == null); if (m_ShutdownAutoResetEvent != null) { throw new System.InvalidOperationException("Can't enqueue workers while shutting down!"); } Enqueue(m_ThreadPoolQueue, inWorker); } m_ManualResetEvent.Set(); // Wake up threads to handle the new item in the queue }
private void ThreadLoop() { s_ContinueThreadLoop = true; while (s_ContinueThreadLoop) { IBlockingQueueServerWorker worker = Dequeue(); if (worker != null) { try { worker.DoWork(); } catch (Exception) { } finally { DisposableBase.SafeDispose(ref worker); } } else { // Shutdown the thread: remove ourselves from the thread pool, and exit this loop lock (m_LockObject) { bool didRemove = m_ThreadPool.Remove(Thread.CurrentThread); DebugUtils.AssertDebuggerBreak(didRemove); if ((m_ThreadPool == null) || (m_ThreadPool.Count == 0)) { m_ThreadPool = null; m_ShutdownAutoResetEvent.Set(); } else { Enqueue(m_ThreadPoolQueue, null); // This will cause all remaining threads to exit m_ManualResetEvent.Set(); } break; } } } }
private IBlockingQueueServerWorker Dequeue() { while (true) { DebugUtils.AssertDebuggerBreak(m_ManualResetEvent != null); lock (m_LockObject) { if (m_IsPaused == 0) { if (m_ThreadPoolQueue.Count > 0) { IBlockingQueueServerWorker worker = m_ThreadPoolQueue.First.Value; m_ThreadPoolQueue.RemoveFirst(); if (m_ThreadPoolQueue.Count > 0) { m_ManualResetEvent.Set(); } else { m_ManualResetEvent.Reset(); } return(worker); } else { m_ManualResetEvent.Reset(); } } else { m_ManualResetEvent.Reset(); } } m_ManualResetEvent.WaitOne(); // Wait for an item to enter the queue } }