Ejemplo n.º 1
0
        private void Push(T context)
        {
            int currentProcessorId = CurrentProcessorIdHelper.GetCurrentProcessorId() % _perCoreContexts.Length;
            var core = _perCoreContexts[currentProcessorId];

            for (int i = 0; i < core.Length; i++)
            {
                if (core[i] != null)
                {
                    continue;
                }
                if (Interlocked.CompareExchange(ref core[i], context, null) == null)
                {
                    return;
                }
            }

            if (LowMemoryFlag.IsRaised())
            {
                context.Dispose();
                return;
            }

            // couldn't find a place for it, let's add it to the global list
            _globalQueue.Enqueue(context);
        }
Ejemplo n.º 2
0
        public IDisposable AllocateOperationContext(out T context)
        {
            _cts.Token.ThrowIfCancellationRequested();
            var coreItems = _perCoreContexts[CurrentProcessorIdHelper.GetCurrentProcessorId() % _perCoreContexts.Length];

            for (int i = 0; i < coreItems.Length; i++)
            {
                context = coreItems[i];
                if (context == null)
                {
                    continue;
                }

                if (Interlocked.CompareExchange(ref coreItems[i], null, context) != context)
                {
                    continue;
                }

                if (context.InUse.Raise() == false)
                {
                    // This what ensures that we work correctly with races from other threads
                    // if there is a context switch at the wrong time
                    continue;
                }
                context.Renew();
                return(new ReturnRequestContext
                {
                    Parent = this,
                    Context = context
                });
            }

            while (_globalQueue.TryDequeue(out context))
            {
                if (context.InUse.Raise() == false)
                {
                    continue;
                }

                context.Renew();
                return(new ReturnRequestContext
                {
                    Parent = this,
                    Context = context
                });
            }

            // no choice, got to create it
            context = CreateContext();
            context.PoolGeneration = _generation;
            return(new ReturnRequestContext
            {
                Parent = this,
                Context = context
            });
        }
Ejemplo n.º 3
0
        public bool TryPush(T cur)
        {
            var core = _perCoreArrays[CurrentProcessorIdHelper.GetCurrentProcessorId() % _perCoreArrays.Length];

            for (int i = 0; i < core.Length; i++)
            {
                if (core[i] != null)
                    continue;
                if (Interlocked.CompareExchange(ref core[i], cur, null) == null)
                    return true;
            }
            return false;
        }
Ejemplo n.º 4
0
        public bool TryPull(out T output)
        {
            var coreItems = _perCoreArrays[CurrentProcessorIdHelper.GetCurrentProcessorId() % _perCoreArrays.Length];

            for (int i = 0; i < coreItems.Length; i++)
            {
                var cur = coreItems[i];
                if (cur == null)
                    continue;

                if (Interlocked.CompareExchange(ref coreItems[i], null, cur) != cur)
                    continue;
                output = cur;
                return true;
            }
            output = default;
            return false;
        }
Ejemplo n.º 5
0
        public void Log(ref LogEntry entry, TaskCompletionSource <object> tcs = null)
        {
            var state = _localState.Value;

            if (state.Generation != _generation)
            {
                state = _localState.Value = GenerateThreadWriterState();
            }

            int currentProcessNumber = CurrentProcessorIdHelper.GetCurrentProcessorId() % _freePooledMessageEntries.Length;
            var pool = _freePooledMessageEntries[currentProcessNumber];

            if (pool.TryDequeue(out var item))
            {
                item.Data.SetLength(0);
                item.WebSocketsList.Clear();
                item.Task = tcs;
                state.ForwardingStream.Destination = item.Data;
            }
            else
            {
                item = new LogMessageEntry {
                    Task = tcs
                };
                state.ForwardingStream.Destination = new MemoryStream();
            }

            foreach (var kvp in _listeners)
            {
                if (kvp.Value.Filter.Forward(ref entry))
                {
                    item.WebSocketsList.Add(kvp.Key);
                }
            }

            WriteEntryToWriter(state.Writer, ref entry);
            item.Data = state.ForwardingStream.Destination;
            Debug.Assert(item.Data != null);
            item.Type = entry.Type;

            _activePoolMessageEntries[currentProcessNumber].Enqueue(item, 128);

            _hasEntries.Set();
        }