private IAsyncResult StartInternalRead(Socket streamSocket, SocketStreamAsyncArgs readArgs, byte[] buffer, int offset, int size, AsyncCallback callback, object state) { IAsyncResult asyncResult; try { SocketStream.IoReq ioReq = new SocketStream.IoReq(state, callback); ioReq.RecordUserBuffer(buffer, offset, size); ioReq.InternalBuffer = readArgs.InternalBuffer; readArgs.SetBuffer(ioReq.InternalBuffer.Buffer, 0, size); readArgs.UserToken = ioReq; SocketStream.Tracer.TraceDebug((long)this.GetHashCode(), "ReceiveAsync called"); if (!streamSocket.ReceiveAsync(readArgs)) { SocketStream.Tracer.TraceDebug((long)this.GetHashCode(), "ReceiveAsync sync completion"); this.IO_Completed(null, readArgs); } asyncResult = ioReq.AsyncResult; } catch (Exception ex) { if (ex is ThreadAbortException || ex is StackOverflowException || ex is OutOfMemoryException) { throw; } throw new IOException(ex.Message, ex); } return(asyncResult); }
private void ReleaseInternalIoResources() { int num = Interlocked.Exchange(ref this.m_readIsBusy, 1); if (num != 0) { int num2 = 10; int num3 = num2 * 10; do { Thread.Sleep(100); num = Interlocked.Exchange(ref this.m_readIsBusy, 1); }while (num != 0 && --num3 > 0); if (num != 0) { this.m_buffersWereLeaked = true; SocketStream.Tracer.TraceError <bool>((long)this.GetHashCode(), "buffer leak: {0}", this.m_buffersWereLeaked); ReplayCrimsonEvents.SocketStreamLeakOnClose.LogPeriodic <int>(Environment.MachineName, Parameters.CurrentValues.DefaultEventSuppressionInterval, num2); return; } } if (this.m_readArgs != null) { SocketStreamAsyncArgs readArgs = this.m_readArgs; this.m_readArgs = null; this.ReleaseArgsToPools(readArgs); } this.m_bufIsAllocated = false; Interlocked.Exchange(ref this.m_readIsBusy, 0); }
private void BindArgsForUse(SimpleBuffer buf, SocketStreamAsyncArgs args) { args.InternalBuffer = buf; args.CompletionRtn = new EventHandler <SocketAsyncEventArgs>(this.IO_Completed); args.Completed += args.CompletionRtn; args.SetBuffer(buf.Buffer, 0, buf.Buffer.Length); }
public override IAsyncResult BeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, object state) { if (!this.CanRead) { throw new InvalidOperationException("net_writeonlystream"); } if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset < 0 || offset > buffer.Length) { throw new ArgumentOutOfRangeException("offset"); } if (size < 0 || size > buffer.Length - offset) { throw new ArgumentOutOfRangeException("size"); } Socket streamSocket = this.m_StreamSocket; if (streamSocket == null) { throw new IOException("net_io_readfailure"); } SocketStreamAsyncArgs socketStreamAsyncArgs = this.ObtainArgsForStartRead(size); if (socketStreamAsyncArgs != null) { return(this.StartInternalRead(streamSocket, socketStreamAsyncArgs, buffer, offset, size, callback, state)); } return(streamSocket.BeginReceive(buffer, offset, size, SocketFlags.None, callback, state)); }
private void ReleaseArgsToPools(SocketStreamAsyncArgs args) { SimpleBuffer internalBuffer = args.InternalBuffer; args.Completed -= args.CompletionRtn; args.CompletionRtn = null; args.InternalBuffer = null; if (internalBuffer != null) { this.m_bufPool.TryReturnObject(internalBuffer); } if (!this.m_asyncArgsPool.TryReturnObject(args)) { args.Dispose(); } }
private SocketStreamAsyncArgs ObtainInternalBuffer(int readSize) { SocketStreamAsyncArgs socketStreamAsyncArgs = null; SimpleBuffer simpleBuffer = null; bool flag = false; try { simpleBuffer = this.m_bufPool.TryGetObject(readSize); if (simpleBuffer == null) { if (readSize <= this.m_bufPool.BufferSize) { ReplayCrimsonEvents.SocketStreamBufferExhaustion.LogPeriodic(Environment.MachineName, Parameters.CurrentValues.DefaultEventSuppressionInterval); } return(null); } socketStreamAsyncArgs = this.m_asyncArgsPool.TryGetObject(); if (socketStreamAsyncArgs == null) { this.m_extraArgCount++; socketStreamAsyncArgs = new SocketStreamAsyncArgs(false); } this.BindArgsForUse(simpleBuffer, socketStreamAsyncArgs); this.m_readArgs = socketStreamAsyncArgs; this.m_bufIsAllocated = true; flag = true; } finally { if (!flag) { if (socketStreamAsyncArgs != null) { this.ReleaseArgsToPools(socketStreamAsyncArgs); socketStreamAsyncArgs = null; } else if (simpleBuffer != null) { this.m_bufPool.TryReturnObject(simpleBuffer); simpleBuffer = null; } } } return(socketStreamAsyncArgs); }
private SocketStreamAsyncArgs ObtainArgsForStartRead(int readSize) { SocketStreamAsyncArgs socketStreamAsyncArgs = null; if (this.m_asyncArgsPool == null) { return(null); } int num = Interlocked.Exchange(ref this.m_readIsBusy, 1); if (num == 1) { return(null); } try { if (!this.m_bufIsAllocated) { socketStreamAsyncArgs = this.ObtainInternalBuffer(readSize); if (socketStreamAsyncArgs == null) { return(null); } } socketStreamAsyncArgs = this.m_readArgs; if (readSize > socketStreamAsyncArgs.InternalBuffer.Buffer.Length) { socketStreamAsyncArgs = null; } } finally { if (socketStreamAsyncArgs == null) { Interlocked.Exchange(ref this.m_readIsBusy, 0); } } return(socketStreamAsyncArgs); }