/// <summary> /// Fetches available existing chunk from cache or creates a new one. /// Called by new sockets by incipient connections /// </summary> internal MemChunk MakeOrReuseChunk() { var chunks = m_Chunks; MemChunk chunk = null; if (chunks != null) { var now = App.TimeSource.UTCNow; lock (m_Chunks)//since this method is called on new socket creation, it is OK to lock for short time { for (var i = 0; i < m_Chunks.Count; i++) { chunk = m_Chunks[i]; if (chunk.Acquired) { continue; //is already taken by some socket } if ((now - chunk._LastReleaseUtc).TotalSeconds >= CHUNK_DORMANT_PERIOD_SEC) //chunk must be in the pool for the specified minimum 'rest' time { // this is needed so all pending async socket operations timeout chunk.Acquired = true; return(chunk); } } } } //otherwise create new chunk, no need to add it to pool here. The release will do it later (if ever called) chunk = new MemChunk(Consts.DEFAULT_SERIALIZER_STREAM_CAPACITY); return(chunk); }
private int serialize(MemChunk chunk, WireFrame frame, Msg msg) { chunk.Position = sizeof(int); frame.Serialize(chunk); Binding.Serializer.Serialize(chunk, msg); var size = (int)chunk.Position; //includes 4 byte len prefix var buff = chunk.GetBuffer(); //no stream expansion beyond this point buff.WriteBEInt32(0, size); return(size); }
internal void ReleaseChunk(MemChunk chunk) { if (chunk == null || !Running) { return; } chunk.Acquired = false; chunk._LastReleaseUtc = App.TimeSource.UTCNow; WriteLog(LogSrc.Any, Log.MessageType.TraceGlue, "Chunk released back to pool; Used {0} capacity {1} ".Args(chunk.stat_MaxUsedPosition, chunk.stat_MaxLength)); var chunks = m_Chunks; if (chunks == null) { return; } lock (chunks) { if (m_Chunks.Count < m_MaxChunkPoolCount) { for (var i = 0; i < m_Chunks.Count; i++) { if (object.ReferenceEquals(m_Chunks[i], chunk)) { return; //already in pool } } chunks.Add(chunk); } } }
internal void ReleaseChunk(MemChunk chunk) { if (chunk==null || !Running) return; chunk.Acquired = false; chunk._LastReleaseUtc = App.TimeSource.UTCNow; WriteLog(LogSrc.Any, Log.MessageType.TraceGlue, "Chunk released back to pool; Used {0} capacity {1} ".Args(chunk.stat_MaxUsedPosition, chunk.stat_MaxLength)); var chunks = m_Chunks; if (chunks==null) return; lock(chunks) { if (m_Chunks.Count < m_MaxChunkPoolCount) { for(var i=0; i<m_Chunks.Count; i++) if (object.ReferenceEquals(m_Chunks[i], chunk)) return;//already in pool chunks.Add(chunk); } } }
/// <summary> /// Fetches available existing chunk from cache or creates a new one. /// Called by new sockets by incipient connections /// </summary> internal MemChunk MakeOrReuseChunk() { var chunks = m_Chunks; MemChunk chunk = null; if (chunks!=null) { var now = App.TimeSource.UTCNow; lock(m_Chunks)//since this method is called on new socket creation, it is OK to lock for short time { for(var i=0; i<m_Chunks.Count; i++) { chunk = m_Chunks[i]; if (chunk.Acquired) continue;//is already taken by some socket if ((now - chunk._LastReleaseUtc).TotalSeconds >= CHUNK_DORMANT_PERIOD_SEC) //chunk must be in the pool for the specified minimum 'rest' time { // this is needed so all pending async socket operations timeout chunk.Acquired = true; return chunk; } } } } //otherwise create new chunk, no need to add it to pool here. The release will do it later (if ever called) chunk = new MemChunk(Consts.DEFAULT_SERIALIZER_STREAM_CAPACITY); return chunk; }
/// <summary> /// Creates WireMsg around pre-filled memory chunk that includes msg size - first 4 bytes /// </summary> public WireMsg(MemChunk data) : this() { Data = data; }