示例#1
0
        /// <summary>
        /// Allocates a ByteBuf from this ByteBufChunkList if it is not empty.
        /// </summary>
        /// <param name="byteBuf">The allocated ByteBuf</param>
        /// <returns>true, if the ByteBuf be allocated; otherwise, false.</returns>
        public bool Allocate(out ByteBuf byteBuf)
        {
            if (head == null)
            {
                // This ByteBufChunkList is empty
                byteBuf = default(ByteBuf);
                return false;
            }

            for (var cur = head; ;)
            {
                if (!cur.Allocate(out byteBuf))
                {
                    cur = cur.Next;
                    if (cur == null)
                    {
                        return false;
                    }
                }
                else
                {
                    if (cur.Usage < maxUsage) return true;

                    Remove(cur);
                    NextList.Add(cur);
                    return true;
                }
            }
        }
示例#2
0
        /// <summary>
        /// Sends data to this socket with a ByteBuf object that contains data to be sent.
        /// </summary>
        /// <param name="data">A ByteBuf object that contains data to be sent</param>
        public void Send(ByteBuf data)
        {
            EnsureAccessible();
            if (!isConnected)
            {
                throw new InvalidOperationException("The operation is not allowed on non-connected sockets.");
            }

            if (!data.IsReadable())
            {
                throw new ArgumentException("The parameter {0} must contain one or more elements.", "data");
            }

            var dataToken = new SockDataToken(this, data);

            if (parent != null)
            {
                parent.DoSend(dataToken);
            }
            else
            {
                DoSend(dataToken);
            }
            var status = sendStatusQueue.Take();

            if (status == (int)SocketError.Success)
            {
                return;
            }

            // throw a SocketException if theres is an error.
            dataToken.Reset();
            Dispose(true);
            var socketException = new SocketException(status);

            throw socketException;
        }
示例#3
0
 /// <summary>
 /// Releases the ByteBuf back to this ByteChunk
 /// </summary>
 /// <param name="byteBuf">The ByteBuf to be released.</param>
 public void Free(ByteBuf byteBuf)
 {
     segmentQueue.Enqueue(new Segment(byteBuf.Offset, byteBuf.Capacity));
     FreeBytes += segmentSize;
 }
示例#4
0
 /// <summary>
 /// Releases the ByteBuf back to this ByteChunk
 /// </summary>
 /// <param name="byteBuf">The ByteBuf to be released.</param>
 public void Free(ByteBuf byteBuf)
 {
     segmentQueue.Enqueue(new Segment(byteBuf.Offset, byteBuf.Capacity));
     FreeBytes += segmentSize;
 }
示例#5
0
        /// <summary>
        /// Allocates a ByteBuf from this ByteChunk.
        /// </summary>
        /// <param name="byteBuf">The ByteBuf be allocated</param>
        /// <returns>true, if succeed to allocate a ByteBuf; otherwise, false</returns>
        public bool Allocate(out ByteBuf byteBuf)
        {
            if (segmentQueue.Count > 0)
            {
                var segment = segmentQueue.Dequeue();
                FreeBytes -= segmentSize;
                byteBuf = new ByteBuf(this, segment.Offset, segment.Count);
                return true;
            }

            byteBuf = default(ByteBuf);
            return false;
        }
示例#6
0
        /// <summary>
        /// Sends data to this socket with a ByteBuf object that contains data to be sent.
        /// </summary>
        /// <param name="data">A ByteBuf object that contains data to be sent</param>
        public void Send(ByteBuf data)
        {
            EnsureAccessible();
            if (!isConnected)
            {
                throw new InvalidOperationException("The operation is not allowed on non-connected sockets.");
            }

            if (!data.IsReadable())
            {
                throw new ArgumentException("The parameter {0} must contain one or more elements.", "data");
            }

            var dataToken = new SockDataToken(this, data);
            if (parent != null)
            {
                parent.DoSend(dataToken);
            }
            else
            {
                DoSend(dataToken);
            }
            var status = sendStatusQueue.Take();
            if (status == (int) SocketError.Success) return;

            // throw a SocketException if theres is an error.
            dataToken.Reset();
            Dispose(true);
            var socketException = new SocketException(status);
            throw socketException;
        }
示例#7
0
        /// <summary>
        /// Writes data to the stream.
        /// </summary>
        /// <param name="buffer">Buffer to write from.</param>
        /// <param name="offset">Offset into the buffer from where we'll start writing.</param>
        /// <param name="count">Number of bytes to write.</param>
        public override void Write(byte[] buffer, int offset, int count)
        {
            try
            {
                var remainingBytes = count;
                var newOffset = offset;
                while (0 < remainingBytes)
                {
                    if (sendDataCache == null)
                    {
                        sendDataCache = bufPool.Allocate();
                    }

                    if (sendDataCache.WritableBytes > remainingBytes)
                    {
                        sendDataCache.WriteBytes(buffer, newOffset, remainingBytes);
                        return;
                    }

                    var sendCount = sendDataCache.WritableBytes;
                    sendDataCache.WriteBytes(buffer, newOffset, sendCount);
                    streamSocket.Send(sendDataCache);
                    sendDataCache = null;

                    newOffset += sendCount;
                    remainingBytes -= sendCount;
                }
            }
            catch (Exception e)
            {
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException)
                {
                    throw;
                }

                // some sort of error occurred on the socked call,
                // set the SocketException as InnerException and throw
                throw new IOException(string.Format("Unable to write data to the transport connection: {0}.", e.Message), e);
            }
        }
 /// <summary>
 /// Sends data to this socket with a ByteBuf object that contains data to be sent.
 ///
 /// The DefaultSocketWrapper does not support this function.
 /// </summary>
 /// <param name="data">A ByteBuf object that contains data to be sent</param>
 public void Send(ByteBuf data)
 {
     throw new NotImplementedException();
 }
示例#9
0
        /// <summary>
        /// Flushes data in send cache to the stream.
        /// </summary>
        public override void Flush()
        {
            if (sendDataCache != null && sendDataCache.IsReadable())
            {
                try
                {
                    streamSocket.Send(sendDataCache);
                    sendDataCache = null;
                }
                catch (Exception e)
                {
                    if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException)
                    {
                        throw;
                    }

                    // some sort of error occurred on the socked call,
                    // set the SocketException as InnerException and throw
                    throw new IOException(string.Format("Unable to write data to the transport connection: {0}.", e.Message), e);
                }
            }
        }
示例#10
0
        /// <summary>
        /// Reads a byte from the stream and advances the position within the stream by one byte, or returns -1 if at the end of the stream.
        /// </summary>
        /// <returns>
        /// The unsigned byte cast to an Int32, or -1 if at the end of the stream.
        /// </returns>
        public override int ReadByte()
        {
            if (recvDataCache == null || !recvDataCache.IsReadable())
            {
                recvDataCache = streamSocket.Receive();
            }

            return recvDataCache.ReadByte();
        }
示例#11
0
        /// <summary>
        /// Deallocates a ByteBuf back to this ByteBufPool.
        /// </summary>
        /// <param name="byteBuf">The ByteBuf to be release.</param>
        public void Free(ByteBuf byteBuf)
        {
            if (byteBuf.ByteBufChunk == null || byteBuf.Capacity == 0 || byteBuf.ByteBufChunk.Size < byteBuf.Offset + byteBuf.Capacity)
            {
                throw new Exception("Attempt to free invalid byteBuf");
            }

            if (byteBuf.Capacity != SegmentSize)
            {
                throw new ArgumentException("Segment was not from the same byte arena", "byteBuf");
            }

            bool mustDestroyChunk;
            var chunk = byteBuf.ByteBufChunk;
            lock (this)
            {
                mustDestroyChunk = !chunk.Parent.Free(chunk, byteBuf);
            }

            if (!mustDestroyChunk) return;

            // Destroy chunk not need to be called while holding the synchronized lock.
            chunk.Parent = null;
            chunk.Dispose();
        }
示例#12
0
 public RequestContext(SocketOperation operation, ByteBuf data)
 {
     Operation = operation;
     Data = data;
 }
示例#13
0
        /// <summary>
        /// Sends data to this socket with a ByteBuf object that contains data to be sent.
        /// </summary>
        /// <param name="data">A ByteBuf object that contains data to be sent</param>
        public void Send(ByteBuf data)
        {
            EnsureAccessible();
            if (!isConnected)
            {
                throw new InvalidOperationException("The operation is not allowed on non-connected sockets.");
            }
            if (!data.IsReadable())
            {
                throw new ArgumentException("The parameter {0} must contain one or more elements.", "data");
            }

            var context = new RequestContext(SocketOperation.Send, data);
            DoSend(GenerateUniqueKey(), context);

            var status = sendStatusQueue.Take();
            if (status == (int)SocketError.Success) return;

            // throw a SocketException if theres is an error.
            Dispose(true);
            var socketException = new SocketException(status);
            throw socketException;
        }
示例#14
0
 public RequestContext(SocketOperation operation, ByteBuf data)
 {
     Operation = operation;
     Data      = data;
 }
示例#15
0
        /// <summary>
        /// Reads data from the stream.
        /// </summary>
        /// <param name="buffer">Buffer to read into.</param>
        /// <param name="offset">Offset into the buffer where we're to read.</param>
        /// <param name="count">Number of bytes to read.</param>
        /// <returns>Number of bytes we read.</returns>
        public override int Read(byte[] buffer, int offset, int count)
        {
            try
            {
                if (recvDataCache == null)
                {
                    recvDataCache = streamSocket.Receive();
                }

                if (!recvDataCache.IsReadable())
                {
                    recvDataCache.Release();
                    recvDataCache = null;
                    return 0;
                }

                var bytesRemaining = count;
                while (recvDataCache != null && recvDataCache.IsReadable() && bytesRemaining > 0)
                {
                    var bytesToRead = Math.Min(bytesRemaining, recvDataCache.ReadableBytes);
                    bytesRemaining -= recvDataCache.ReadBytes(buffer, offset + count - bytesRemaining, bytesToRead);
                    if (recvDataCache.IsReadable()) continue;

                    recvDataCache.Release();
                    recvDataCache = null;
                    if (streamSocket.HasData)
                    {
                        recvDataCache = streamSocket.Receive();
                    }
                }

                return count - bytesRemaining;
            }
            catch (Exception e)
            {
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException)
                {
                    throw;
                }

                // some sort of error occurred on the socket call,
                // set the SocketException as InnerException and throw
                throw new IOException(string.Format("Unable to read data from the transport connection: {0}.", e.Message), e);
            }
        }
示例#16
0
 /// <summary>
 /// Sends data to this socket with a ByteBuf object that contains data to be sent.
 /// 
 /// The DefaultSocketWrapper does not support this function.
 /// </summary>
 /// <param name="data">A ByteBuf object that contains data to be sent</param>
 public void Send(ByteBuf data)
 {
     throw new NotImplementedException();
 }
示例#17
0
        /// <summary>
        /// Reads a byte from the stream and advances the position within the stream by one byte, or returns -1 if at the end of the stream.
        /// </summary>
        /// <returns>
        /// The unsigned byte cast to an Int32, or -1 if at the end of the stream.
        /// </returns>
        public override int ReadByte()
        {
            if (recvDataCache == null || !recvDataCache.IsReadable())
            {
                recvDataCache = streamSocket.Receive();
            }

            var v = recvDataCache.ReadByte();
            if (recvDataCache.IsReadable()) return v;

            // Release cache if it is not readable. If we do not reset the cache here,
            // the cache will be used in next Read() that caused 0 bytes return.
            recvDataCache.Release();
            recvDataCache = null;
            return v;
        }
示例#18
0
        private void WriteReadByteBufTest(ByteBuf byteBuf)
        {
            var initWriteIndex = byteBuf.WriterIndex;
            var initReadIndex = byteBuf.WriterIndex;
            Assert.AreEqual(initWriteIndex, initReadIndex);
            Assert.AreEqual(byteBuf.Capacity, byteBuf.WritableBytes);
            Assert.AreEqual(0, byteBuf.ReadableBytes);
            Assert.IsFalse(byteBuf.IsReadable());
            Assert.IsTrue(byteBuf.IsWritable());

            // Verify WriteBytes() function
            const string writeStr = "Write bytes to ByteBuf.";
            var writeBytes = Encoding.UTF8.GetBytes(writeStr);
            byteBuf.WriteBytes(writeBytes, 0, writeBytes.Length);

            Assert.AreEqual(initWriteIndex + writeBytes.Length, byteBuf.WriterIndex);
            Assert.AreEqual(byteBuf.Capacity - writeBytes.Length, byteBuf.WritableBytes);
            Assert.AreEqual(writeBytes.Length, byteBuf.ReadableBytes);
            Assert.AreEqual(initReadIndex, byteBuf.ReaderIndex);
            Assert.IsTrue(byteBuf.IsReadable());

            // Verify ReadBytes() function
            var readBytes = new byte[writeBytes.Length];
            var ret = byteBuf.ReadBytes(readBytes, 0, readBytes.Length);
            Assert.AreEqual(writeBytes.Length, ret);
            var readStr = Encoding.UTF8.GetString(readBytes, 0, ret);
            Assert.AreEqual(writeStr, readStr);

            Assert.AreEqual(initWriteIndex + writeBytes.Length, byteBuf.WriterIndex);
            Assert.AreEqual(byteBuf.Capacity - writeBytes.Length, byteBuf.WritableBytes);
            Assert.AreEqual(0, byteBuf.ReadableBytes);
            Assert.AreEqual(initReadIndex + ret, byteBuf.ReaderIndex);

            // Verify ReadByte() function
            byteBuf.WriteBytes(writeBytes, 0, 1);
            var retByte = byteBuf.ReadByte();
            Assert.AreEqual(writeBytes[0], retByte);

            // Verify clear() function
            byteBuf.Clear();
            Assert.AreEqual(0, byteBuf.ReaderIndex);
            Assert.AreEqual(0, byteBuf.WriterIndex);
        }
示例#19
0
        /// <summary>
        /// Releases the segment back to its ByteBufChunk.
        /// </summary>
        /// <param name="chunk">The ByteBufChunk that contains the ByteBuf</param>
        /// <param name="byteBuf">The ByteBuf to be released.</param>
        /// <returns>
        /// true, if the ByteBuf be released and NOT need to destroy the
        /// ByteBufChunk (its usage is 0); otherwise, false.
        /// </returns>
        public bool Free(ByteBufChunk chunk, ByteBuf byteBuf)
        {
            chunk.Free(byteBuf);
            if (chunk.Usage >= minUsage) return true;

            Remove(chunk);
            // Move the ByteBufChunk down the ByteBufChunkList linked-list.
            return MoveInternal(chunk);
        }