Ejemplo n.º 1
0
        public HeapMemory CreateOutgoingMessage(ArraySegment <byte> payload, out bool dealloc)
        {
            // Increment the sequence number
            _lastOutboundSequenceNumber++;

            // Allocate the memory
            HeapMemory memory = MemoryManager.Alloc((uint)payload.Count + 4);

            // Write headers
            memory.Buffer[0] = HeaderPacker.Pack((byte)MessageType.Data, false);
            memory.Buffer[1] = channelId;

            // Write the sequence
            memory.Buffer[2] = (byte)_lastOutboundSequenceNumber;
            memory.Buffer[3] = (byte)(_lastOutboundSequenceNumber >> 8);

            // Copy the payload
            Buffer.BlockCopy(payload.Array, payload.Offset, memory.Buffer, 4, payload.Count);

            // Add the memory to pending
            _sendSequencer[_lastOutboundSequenceNumber] = new PendingOutgoingPacket()
            {
                Alive     = true,
                Sequence  = _lastOutboundSequenceNumber,
                Attempts  = 1,
                LastSent  = DateTime.Now,
                FirstSent = DateTime.Now,
                Memory    = memory
            };

            // Tell the caller NOT to dealloc the memory, the channel needs it for resend purposes.
            dealloc = false;

            return(memory);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Apply filter to an unmanaged image or its part.
        /// </summary>
        ///
        /// <param name="image">Unmanaged image to apply filter to.</param>
        /// <param name="rect">Image rectangle for processing by the filter.</param>
        ///
        /// <remarks>The method applies the filter directly to the provided source image.</remarks>
        ///
        /// <exception cref="UnsupportedImageFormatException">Unsupported pixel format of the source image.</exception>
        ///
        public void ApplyInPlace(UnmanagedImage image, Rectangle rect)
        {
            // check pixel format of the source image
            CheckSourceFormat(image.PixelFormat);

            // validate rectangle
            rect.Intersect(new Rectangle(0, 0, image.Width, image.Height));

            // process the filter if rectangle is not empty
            if ((rect.Width | rect.Height) != 0)
            {
                // create a copy of the source image
                int size = image.Stride * image.Height;

                IntPtr imageCopy = MemoryManager.Alloc(size);
                AForge.SystemTools.CopyUnmanagedMemory(imageCopy, image.ImageData, size);

                // process the filter
                ProcessFilter(
                    new UnmanagedImage(imageCopy, image.Width, image.Height, image.Stride, image.PixelFormat),
                    image, rect);

                MemoryManager.Free(imageCopy);
            }
        }
 public void ApplyInPlace(UnmanagedImage image, Rectangle rect)
 {
     this.CheckSourceFormat(image.PixelFormat);
     rect.Intersect(new Rectangle(0, 0, image.Width, image.Height));
     if ((rect.Width | rect.Height) != 0)
     {
         int    size = image.Stride * image.Height;
         IntPtr dst  = MemoryManager.Alloc(size);
         SystemTools.CopyUnmanagedMemory(dst, image.ImageData, size);
         this.ProcessFilter(new UnmanagedImage(dst, image.Width, image.Height, image.Stride, image.PixelFormat), image, rect);
         MemoryManager.Free(dst);
     }
 }
        public ArraySegment <byte>?HandleIncomingMessagePoll(ArraySegment <byte> payload, out bool hasMore)
        {
            // Read the sequence number
            ushort sequence = (ushort)(payload.Array[payload.Offset] | (ushort)(payload.Array[payload.Offset + 1] << 8));

            if (SequencingUtils.Distance(sequence, _incomingLowestAckedSequence, sizeof(ushort)) <= 0 || _receiveSequencer[sequence].Alive)
            {
                // We have already acked this message. Ack again

                SendAck(sequence);

                hasMore = false;
                return(null);
            }
            else if (sequence == _incomingLowestAckedSequence + 1)
            {
                // This is the packet right after

                // If the one after is alive, we give set hasMore to true
                hasMore = _receiveSequencer[_incomingLowestAckedSequence + 2].Alive;

                _incomingLowestAckedSequence++;

                // Send ack
                SendAck(sequence);

                return(new ArraySegment <byte>(payload.Array, payload.Offset + 2, payload.Count - 2));
            }
            else if (SequencingUtils.Distance(sequence, _incomingLowestAckedSequence, sizeof(ushort)) > 0 && !_receiveSequencer[sequence].Alive)
            {
                // Alloc payload plus header memory
                HeapMemory memory = MemoryManager.Alloc((uint)payload.Count - 2);

                // Copy the payload
                Buffer.BlockCopy(payload.Array, payload.Offset + 2, memory.Buffer, 0, payload.Count - 2);

                // Add to sequencer
                _receiveSequencer[sequence] = new PendingIncomingPacket()
                {
                    Alive    = true,
                    Memory   = memory,
                    Sequence = sequence
                };

                // Send ack
                SendAck(sequence);
            }

            hasMore = false;
            return(null);
        }
Ejemplo n.º 5
0
        internal HeapMemory CreateOutgoingHeartbeatMessage()
        {
            // Increment the sequence number
            _lastOutboundSequenceNumber++;

            // Allocate the memory
            HeapMemory memory = MemoryManager.Alloc(3);

            // Write headers
            memory.Buffer[0] = HeaderPacker.Pack((byte)MessageType.Heartbeat, false);

            // Write the sequence
            memory.Buffer[1] = (byte)_lastOutboundSequenceNumber;
            memory.Buffer[2] = (byte)(_lastOutboundSequenceNumber >> 8);

            return(memory);
        }
Ejemplo n.º 6
0
        public HeapMemory CreateOutgoingMessage(ArraySegment <byte> payload, out bool dealloc)
        {
            // Allocate the memory
            HeapMemory memory = MemoryManager.Alloc((uint)payload.Count + 2);

            // Write headers
            memory.Buffer[0] = HeaderPacker.Pack((byte)MessageType.Data, false);
            memory.Buffer[1] = channelId;

            // Copy the payload
            Buffer.BlockCopy(payload.Array, payload.Offset, memory.Buffer, 2, payload.Count);

            // Tell the caller to deallc the memory
            dealloc = true;

            return(memory);
        }
Ejemplo n.º 7
0
        private void SendAck(ushort sequence)
        {
            // Alloc ack memory
            HeapMemory ackMemory = MemoryManager.Alloc(4);

            // Write header
            ackMemory.Buffer[0] = HeaderPacker.Pack((byte)MessageType.Ack, false);
            ackMemory.Buffer[1] = (byte)channelId;

            // Write sequence
            ackMemory.Buffer[2] = (byte)sequence;
            ackMemory.Buffer[3] = (byte)(sequence >> 8);

            // Send ack
            connection.SendRaw(new ArraySegment <byte>(ackMemory.Buffer, 0, 4), false);

            // Return memory
            MemoryManager.DeAlloc(ackMemory);
        }
Ejemplo n.º 8
0
        public HeapMemory CreateOutgoingMessage(ArraySegment <byte> payload, out bool dealloc)
        {
            // Increment the sequence number
            _lastOutboundSequenceNumber++;

            // Allocate the memory
            HeapMemory memory = MemoryManager.Alloc((uint)payload.Count + 4);

            // Write headers
            memory.Buffer[0] = HeaderPacker.Pack((byte)MessageType.Data, false);
            memory.Buffer[1] = channelId;

            // Write the sequence
            memory.Buffer[2] = (byte)_lastOutboundSequenceNumber;
            memory.Buffer[3] = (byte)(_lastOutboundSequenceNumber >> 8);

            // Copy the payload
            Buffer.BlockCopy(payload.Array, payload.Offset, memory.Buffer, 4, payload.Count);

            // Tell the caller to deallc the memory
            dealloc = true;

            return(memory);
        }
Ejemplo n.º 9
0
        internal static void HandleIncomingMessage(ArraySegment <byte> payload, Connection connection, SocketConfig activeConfig)
        {
            // This is where all data packets arrive after passing the connection handling.

            // TODO:
            // 1. Fragmentation
            // 2. Delay to pack messages

            byte channelId = payload.Array[payload.Offset];

            if (channelId < 0 || channelId >= connection.Channels.Length)
            {
                // ChannelId out of range
                return;
            }

            ArraySegment <byte>?incomingMessage = connection.Channels[channelId].HandleIncomingMessagePoll(new ArraySegment <byte>(payload.Array, payload.Offset + 1, payload.Count - 1), out bool hasMore);

            if (incomingMessage != null)
            {
                // Alloc memory that can be borrowed to userspace
                HeapMemory memory = MemoryManager.Alloc((uint)incomingMessage.Value.Count);

                // Copy payload to borrowed memory
                Buffer.BlockCopy(incomingMessage.Value.Array, incomingMessage.Value.Offset, memory.Buffer, 0, incomingMessage.Value.Count);

                // Send to userspace
                connection.Socket.UserEventQueue.Enqueue(new NetworkEvent()
                {
                    Connection        = connection,
                    Socket            = connection.Socket,
                    Type              = NetworkEventType.Data,
                    AllowUserRecycle  = true,
                    Data              = new ArraySegment <byte>(memory.Buffer, (int)memory.VirtualOffset, (int)memory.VirtualCount),
                    InternalMemory    = memory,
                    SocketReceiveTime = DateTime.Now,
                    ChannelId         = channelId
                });
            }

            if (hasMore)
            {
                HeapMemory messageMemory = null;

                do
                {
                    messageMemory = connection.Channels[channelId].HandlePoll();

                    if (messageMemory != null)
                    {
                        // Send to userspace
                        connection.Socket.UserEventQueue.Enqueue(new NetworkEvent()
                        {
                            Connection        = connection,
                            Socket            = connection.Socket,
                            Type              = NetworkEventType.Data,
                            AllowUserRecycle  = true,
                            Data              = new ArraySegment <byte>(messageMemory.Buffer, (int)messageMemory.VirtualOffset, (int)messageMemory.VirtualCount),
                            InternalMemory    = messageMemory,
                            SocketReceiveTime = DateTime.Now,
                            ChannelId         = channelId
                        });
                    }
                }while (messageMemory != null);
            }
        }