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); }
/// <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); }
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); }
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); }
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); }
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); }
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); } }