public static Task WriteAndFlushManyAsync(this IChannelHandlerContext context, ICollection <object> messages) { if (messages is null || 0u >= (uint)messages.Count) { return(TaskUtil.Completed); } var taskList = ThreadLocalList <Task> .NewInstance(); foreach (object m in messages) { taskList.Add(context.WriteAsync(m)); } context.Flush(); var writeCloseCompletion = Task.WhenAll(taskList); writeCloseCompletion.ContinueWith(s_returnAfterWriteAction, taskList, TaskContinuationOptions.ExecuteSynchronously); return(writeCloseCompletion); }
private void AcquireAllLocks() { bool lockTaken = false; for (ThreadLocalList <T> list = this.m_headList; list != null; list = list.m_nextList) { try { Monitor.Enter(list, ref lockTaken); } finally { if (lockTaken) { list.m_lockTaken = true; lockTaken = false; } } } }
private List <T> ToList() { Debug.Assert(Monitor.IsEntered(GlobalListsLock)); List <T> list = new List <T>(); ThreadLocalList currentList = _headList; while (currentList != null) { Node currentNode = currentList._head; while (currentNode != null) { list.Add(currentNode._value); currentNode = currentNode._next; } currentList = currentList._nextList; } return(list); }
private bool Steal(out T result, bool take) { bool loop; List <int> versionsList = new List <int>(); do { versionsList.Clear(); loop = false; ThreadLocalList currentList = _headList; while (currentList != null) { versionsList.Add(currentList._version); if (currentList._head != null && TrySteal(currentList, out result, take)) { return(true); } currentList = currentList._nextList; } currentList = _headList; foreach (int version in versionsList) { if (version != currentList._version) { loop = true; if (currentList._head != null && TrySteal(currentList, out result, take)) { return(true); } } currentList = currentList._nextList; } } while (loop); result = default(T); return(false); }
/// <summary> /// Local helper function to retrieve a thread local list by a thread object /// </summary> /// <param name="forceCreate">Create a new list if the thread does ot exist</param> /// <returns>The local list object</returns> private ThreadLocalList GetThreadList(bool forceCreate) { ThreadLocalList list = _locals.Value; if (list != null) { return(list); } else if (forceCreate) { // Acquire the lock to update the _tailList pointer lock (GlobalListsLock) { if (_headList == null) { list = new ThreadLocalList(Environment.CurrentManagedThreadId); _headList = list; _tailList = list; } else { list = GetUnownedList(); if (list == null) { list = new ThreadLocalList(Environment.CurrentManagedThreadId); _tailList._nextList = list; _tailList = list; } } _locals.Value = list; } } else { return(null); } Debug.Assert(list != null); return(list); }
/// <summary> /// Local helper function to retrieve a thread local list by a thread object /// </summary> /// <param name="forceCreate">Create a new list if the thread does ot exist</param> /// <returns>The local list object</returns> private ThreadLocalList GetThreadList(bool forceCreate) { ThreadLocalList list = m_locals.Value; if (list != null) { return(list); } else if (forceCreate) { // Acquire the lock to update the m_tailList pointer lock (GlobalListsLock) { if (m_headList == null) { list = new ThreadLocalList(Thread.CurrentThread); m_headList = list; m_tailList = list; } else { list = GetUnownedList(); if (list == null) { list = new ThreadLocalList(Thread.CurrentThread); m_tailList.m_nextList = list; m_tailList = list; } } m_locals.Value = list; } } else { return(null); } Debug.Assert(list != null); return(list); }
private void AddInternal(ThreadLocalList list, T item) { bool lockTaken = false; try { Interlocked.Exchange(ref list._currentOp, (int)ListOperation.Add); if (list.Count < 2 || _needSync) { list._currentOp = (int)ListOperation.None; Monitor.Enter(list, ref lockTaken); } list.Add(item, lockTaken); } finally { list._currentOp = (int)ListOperation.None; if (lockTaken) { Monitor.Exit(list); } } }
private void AcquireAllLocks() { Debug.Assert(Monitor.IsEntered(GlobalListsLock)); bool lockTaken = false; ThreadLocalList currentList = _headList; while (currentList != null) { try { Monitor.Enter(currentList, ref lockTaken); } finally { if (lockTaken) { currentList._lockTaken = true; lockTaken = false; } } currentList = currentList._nextList; } }
private void AddInternal(ThreadLocalList <T> list, T item) { bool lockTaken = false; try { Interlocked.Exchange(ref list.m_currentOp, 1); if ((list.Count < 2) || this.m_needSync) { list.m_currentOp = 0; Monitor.Enter(list, ref lockTaken); } list.Add(item, lockTaken); } finally { list.m_currentOp = 0; if (lockTaken) { Monitor.Exit(list); } } }
/// <summary> /// local helper method to acquire all local lists locks /// </summary> private void AcquireAllLocks() { bool lockTaken = false; ThreadLocalList currentList = m_headList; while (currentList != null) { // Try/Finally bllock to avoid thread aport between acquiring the lock and setting the taken flag try { Monitor2.Enter(currentList, ref lockTaken); } finally { if (lockTaken) { currentList.m_lockTaken = true; lockTaken = false; } } currentList = currentList.m_nextList; } }
/// <summary> /// Local helper function to Take or Peek an item from the bag /// </summary> /// <param name="result">To receive the item retrieved from the bag</param> /// <param name="take">True means Take operation, false means Peek operation</param> /// <returns>True if succeeded, false otherwise</returns> private bool TryTakeOrPeek(out T result, bool take) { // Get the local list for that thread, return null if the thread doesn't exit //(this thread never add before) ThreadLocalList list = GetThreadList(false); if (list == null || list.Count == 0) { return(Steal(out result, take)); } bool lockTaken = false; try { if (take) // Take operation { #pragma warning disable 0420 Interlocked.Exchange(ref list._currentOp, (int)ListOperation.Take); #pragma warning restore 0420 //Synchronization cases: // if the list count is less than or equal two to avoid conflict with any stealing thread // if _needSync is set, this means there is a thread that needs to freeze the bag if (list.Count <= 2 || _needSync) { // reset it back to zero to avoid deadlock with stealing thread list._currentOp = (int)ListOperation.None; Monitor.Enter(list, ref lockTaken); // Double check the count and steal if it became empty if (list.Count == 0) { // Release the lock before stealing if (lockTaken) { try { } finally { lockTaken = false; // reset lockTaken to avoid calling Monitor.Exit again in the finally block Monitor.Exit(list); } } return(Steal(out result, true)); } } list.Remove(out result); } else { if (!list.Peek(out result)) { return(Steal(out result, false)); } } } finally { list._currentOp = (int)ListOperation.None; if (lockTaken) { Monitor.Exit(list); } } return(true); }
public void Add(T item) { ThreadLocalList <T> threadList = this.GetThreadList(true); this.AddInternal(threadList, item); }
/// <summary> /// 添加一个数据到 <see cref="ConcurrentBag{T}"/>中。 /// </summary> /// <param name="item"></param> public void Add(T item) { ThreadLocalList list = GetThreadList(true); AddInternal(list, item); }
protected internal override ReadOnlySequence <byte> _GetSequence(int index, int count) { if (0u >= (uint)count) { return(ReadOnlySequence <byte> .Empty); } int i = ToComponentIndex0(index); if (i == ToComponentIndex0(index + count - 1)) { ComponentEntry c = _components[i]; return(c.Buffer.GetSequence(c.Idx(index), count)); } var buffers = ThreadLocalList <ReadOnlyMemory <byte> > .NewInstance(_componentCount); try { while (count > 0) { ComponentEntry c = _components[i]; IByteBuffer s = c.Buffer; int localLength = Math.Min(count, c.EndOffset - index); switch (s.IoBufferCount) { case 0: ThrowHelper.ThrowNotSupportedException(); break; case 1: if (s.IsSingleIoBuffer) { buffers.Add(s.GetReadableMemory(c.Idx(index), localLength)); } else { var sequence0 = s.GetSequence(c.Idx(index), localLength); foreach (var memory in sequence0) { buffers.Add(memory); } } break; default: var sequence = s.GetSequence(c.Idx(index), localLength); foreach (var memory in sequence) { buffers.Add(memory); } break; } index += localLength; count -= localLength; i++; } return(ReadOnlyBufferSegment.Create(buffers)); } finally { buffers.Return(); } }