Exemplo n.º 1
0
        /// <summary>
        /// Schedules the specified object to be released when the caller thread terminates. Note that this operation
        /// is intended to simplify reference counting of ephemeral objects during unit tests. Do not use it beyond the
        /// intended use case.
        /// </summary>
        public static T ReleaseLater <T>(T msg, int decrement)
        {
            var referenceCounted = msg as IReferenceCounted;

            if (referenceCounted != null)
            {
                ThreadDeathWatcher.Watch(Thread.CurrentThread, () =>
                {
                    try
                    {
                        if (!referenceCounted.Release(decrement))
                        {
                            Logger.WarnFormat("Non-zero refCnt: {0}", FormatReleaseString(referenceCounted, decrement));
                        }
                        else
                        {
                            Logger.DebugFormat("Released: {0}", FormatReleaseString(referenceCounted, decrement));
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.WarnFormat("Failed to release an object: {0}", referenceCounted, ex);
                    }
                });
            }
            return(msg);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Schedules the specified object to be released when the caller thread terminates. Note that this operation
        /// is intended to simplify reference counting of ephemeral objects during unit tests. Do not use it beyond the
        /// intended use case.
        /// </summary>
        public static T ReleaseLater <T>(T msg, int decrement)
        {
            if (msg is IReferenceCounted referenceCounted)
            {
                ThreadDeathWatcher.Watch(Thread.CurrentThread, () =>
                {
                    try
                    {
                        if (!referenceCounted.Release(decrement))
                        {
                            Logger.NonZeroRefCnt(referenceCounted, decrement);
                        }
#if DEBUG
                        else
                        {
                            if (Logger.DebugEnabled)
                            {
                                Logger.ReleasedObject(referenceCounted, decrement);
                            }
                        }
#endif
                    }
                    catch (Exception ex)
                    {
                        Logger.FailedToReleaseAObject(referenceCounted, ex);
                    }
                });
            }
            return(msg);
        }
Exemplo n.º 3
0
            internal virtual async Task shutdownAsync()
            {
                if (!closing)
                {
                    closing = true;
                    try
                    {
                        await this.group.ShutdownGracefullyAsync();

                        if (ThreadDeathWatcher.AwaitInactivity(TimeSpan.FromSeconds(2)))
                        {
                            log.Debug("Global event executor finished shutting down.");
                        }
                        else
                        {
                            log.Debug("Global event executor failed to shut down.");
                        }
                    }
                    catch (Exception e)
                    {
                        log.Error("Netty shutdown error", e);
                    }

                    FastThreadLocal.Destroy();
                }
                else
                {
                    log.Debug("Pool already shutting down");
                }
            }
        /// <summary>
        /// Schedules the specified object to be released when the caller thread terminates. Note that this operation
        /// is intended to simplify reference counting of ephemeral objects during unit tests. Do not use it beyond the
        /// intended use case.
        /// </summary>
        public static T ReleaseLater <T>(T msg, int decrement)
        {
            var referenceCounted = msg as IReferenceCounted;

            if (referenceCounted != null)
            {
                ThreadDeathWatcher.Watch(Thread.CurrentThread, () =>
                {
                    try
                    {
                        if (!referenceCounted.Release(decrement))
                        {
                            Debug.Log("Non-zero refCnt: {}");
                        }
                        else
                        {
                            Debug.Log("Released: {}");
                        }
                    }
                    catch (Exception ex)
                    {
                        Debug.Log("Failed to release an object: {}");
                    }
                });
            }
            return(msg);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Should be called if the Thread that uses this cache is about to exist to release resources out of the cache
        /// </summary>
        internal void Free()
        {
            if (_freeTask is object)
            {
                Debug.Assert(_deathWatchThread is object);
                ThreadDeathWatcher.Unwatch(_deathWatchThread, _freeTask);
            }

            Free0();
        }
Exemplo n.º 6
0
        /**
         *  Should be called if the Thread that uses this cache is about to exist to release resources out of the cache
         */
        internal void Free()
        {
            if (this.freeTask != null)
            {
                Debug.Assert(this.deathWatchThread != null);
                ThreadDeathWatcher.Unwatch(this.deathWatchThread, this.freeTask);
            }

            this.Free0();
        }
Exemplo n.º 7
0
        // TODO: Test if adding padding helps under contention
        //private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7;

        internal PoolThreadCache(PoolArena <T> heapArena,
                                 int tinyCacheSize, int smallCacheSize, int normalCacheSize,
                                 int maxCachedBufferCapacity, int freeSweepAllocationThreshold)
        {
            Contract.Requires(maxCachedBufferCapacity >= 0);
            Contract.Requires(freeSweepAllocationThreshold > 0);

            this.freeSweepAllocationThreshold = freeSweepAllocationThreshold;
            this.HeapArena = heapArena;
            if (heapArena != null)
            {
                // Create the caches for the heap allocations
                this.tinySubPageHeapCaches = CreateSubPageCaches(
                    tinyCacheSize, PoolArena <T> .NumTinySubpagePools, SizeClass.Tiny);
                this.smallSubPageHeapCaches = CreateSubPageCaches(
                    smallCacheSize, heapArena.NumSmallSubpagePools, SizeClass.Small);

                this.numShiftsNormalHeap = Log2(heapArena.PageSize);
                this.normalHeapCaches    = CreateNormalCaches(
                    normalCacheSize, maxCachedBufferCapacity, heapArena);

                heapArena.IncrementNumThreadCaches();
            }
            else
            {
                // No heapArea is configured so just null out all caches
                this.tinySubPageHeapCaches  = null;
                this.smallSubPageHeapCaches = null;
                this.normalHeapCaches       = null;
                this.numShiftsNormalHeap    = -1;
            }

            // We only need to watch the thread when any cache is used.
            if (this.tinySubPageHeapCaches != null || this.smallSubPageHeapCaches != null || this.normalHeapCaches != null)
            {
                this.freeTask         = this.Free0;
                this.deathWatchThread = Thread.CurrentThread;

                // The thread-local cache will keep a list of pooled buffers which must be returned to
                // the pool when the thread is not alive anymore.
                ThreadDeathWatcher.Watch(this.deathWatchThread, this.freeTask);
            }
            else
            {
                this.freeTask         = null;
                this.deathWatchThread = null;
            }
        }
Exemplo n.º 8
0
        // TODO: Test if adding padding helps under contention
        //private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7;

        internal PoolThreadCache(PoolArena <T> heapArena, PoolArena <T> directArena,
                                 int tinyCacheSize, int smallCacheSize, int normalCacheSize,
                                 int maxCachedBufferCapacity, int freeSweepAllocationThreshold)
        {
            if (maxCachedBufferCapacity < 0)
            {
                ThrowHelper.ThrowArgumentException_PositiveOrZero(maxCachedBufferCapacity, ExceptionArgument.maxCachedBufferCapacity);
            }

            _freeSweepAllocationThreshold = freeSweepAllocationThreshold;
            HeapArena   = heapArena;
            DirectArena = directArena;
            if (directArena is object)
            {
                tinySubPageDirectCaches = CreateSubPageCaches(
                    tinyCacheSize, PoolArena <T> .NumTinySubpagePools, SizeClass.Tiny);
                smallSubPageDirectCaches = CreateSubPageCaches(
                    smallCacheSize, directArena.NumSmallSubpagePools, SizeClass.Small);

                _numShiftsNormalDirect = Log2(directArena.PageSize);
                normalDirectCaches     = CreateNormalCaches(
                    normalCacheSize, maxCachedBufferCapacity, directArena);

                directArena.IncrementNumThreadCaches();
            }
            else
            {
                // No directArea is configured so just null out all caches
                tinySubPageDirectCaches  = null;
                smallSubPageDirectCaches = null;
                normalDirectCaches       = null;
                _numShiftsNormalDirect   = -1;
            }
            if (heapArena is object)
            {
                // Create the caches for the heap allocations
                tinySubPageHeapCaches = CreateSubPageCaches(
                    tinyCacheSize, PoolArena <T> .NumTinySubpagePools, SizeClass.Tiny);
                smallSubPageHeapCaches = CreateSubPageCaches(
                    smallCacheSize, heapArena.NumSmallSubpagePools, SizeClass.Small);

                _numShiftsNormalHeap = Log2(heapArena.PageSize);
                normalHeapCaches     = CreateNormalCaches(
                    normalCacheSize, maxCachedBufferCapacity, heapArena);

                heapArena.IncrementNumThreadCaches();
            }
            else
            {
                // No heapArea is configured so just null out all caches
                tinySubPageHeapCaches  = null;
                smallSubPageHeapCaches = null;
                normalHeapCaches       = null;
                _numShiftsNormalHeap   = -1;
            }

            // We only need to watch the thread when any cache is used.
            if (tinySubPageDirectCaches is object || smallSubPageDirectCaches is object || normalDirectCaches is object ||
                tinySubPageHeapCaches is object || smallSubPageHeapCaches is object || normalHeapCaches is object)
            {
                if (freeSweepAllocationThreshold < 1)
                {
                    ThrowHelper.ThrowArgumentException_Positive(freeSweepAllocationThreshold, ExceptionArgument.freeSweepAllocationThreshold);
                }
                _freeTask         = Free0;
                _deathWatchThread = Thread.CurrentThread;

                // The thread-local cache will keep a list of pooled buffers which must be returned to
                // the pool when the thread is not alive anymore.
                ThreadDeathWatcher.Watch(_deathWatchThread, _freeTask);
            }
            else
            {
                _freeTask         = null;
                _deathWatchThread = null;
            }
        }
Exemplo n.º 9
0
        /**
         *  Should be called if the Thread that uses this cache is about to exist to release resources out of the cache
         */

        internal void Free()
        {
            ThreadDeathWatcher.Unwatch(this.thread, this.freeTask);
            this.Free0();
        }