private HmuxConnection OpenRecycle() { long now = Utils.CurrentTimeMillis(); HmuxConnection channel = null; lock (this) { if (_idleHead != _idleTail) { channel = _idle[_idleHead]; long freeTime = channel.GetIdleStartTime(); _idle[_idleHead] = null; _idleHead = (_idleHead + _idle.Length - 1) % _idle.Length; if (now < freeTime + _loadBalanceIdleTime) { _activeCount++; channel.ClearIdleStartTime(); channel.ToActive(); Trace.TraceInformation("OpenRecycle '{0}'", channel); return(channel); } } } if (channel != null) { if (_log.IsLoggable(EventLogEntryType.Information)) { _log.Info(this + " close idle " + channel + " expire=" + new DateTime(channel.GetIdleStartTime() * 10 + _loadBalanceIdleTime * 10)); } Trace.TraceInformation("closing expired channel '{0}'", channel); channel.CloseImpl(); } Trace.TraceInformation("OpenRecyle return 'null'"); return(null); }
internal void Free(HmuxConnection channel) { Success(); lock (this) { _activeCount--; bool failing = false; failing = _failTime > 0 || _busyTime > 0; int size = (_idleHead - _idleTail + _idle.Length) % _idle.Length; if (!failing && size < _idleSize) { Trace.TraceInformation("Returning channel '{0}' to pool", channel); _idleHead = (_idleHead + 1) % _idle.Length; _idle[_idleHead] = channel; channel = null; } } long now = Utils.CurrentTimeMillis(); long maxIdleTime = _loadBalanceIdleTime; HmuxConnection oldChannel = null; do { oldChannel = null; lock (this) { if (_idleHead != _idleTail) { int nextTail = (_idleTail + 1) % _idle.Length; oldChannel = _idle[nextTail]; if (oldChannel != null && (oldChannel.GetIdleStartTime() + maxIdleTime) < now) { _idle[nextTail] = null; _idleTail = nextTail; } else { oldChannel = null; } } } if (oldChannel != null) { oldChannel.CloseImpl(); Trace.TraceInformation("closing expired channel '{0}'", oldChannel); } } while (oldChannel != null); if (channel != null) { channel.CloseImpl(); } }