public bool EnqueueOutgoing(OutgoingPacket packet) { int category = (int)packet.Category; if (category >= 0 && category < m_packetOutboxes.Length) { OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; // Not enough tokens in the bucket, queue this packet //check the queue //Dont drop resends this can mess up the buffer pool as well as make the connection situation much worse if (_currentOutboundQueueSize > MAX_TOTAL_QUEUE_SIZE && (packet.Buffer[0] & Helpers.MSG_RESENT) == 0) { //queue already has too much data in it.. //can we drop this packet? byte flags = packet.Buffer[0]; bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0; if (!isReliable && packet.Type != PacketType.PacketAck && packet.Type != PacketType.CompletePingCheck) { //packet is unreliable and will be dropped this.TestReportPacketDrop(packet); packet.DecRef(m_udpServer.ByteBufferPool); } else { if (_currentOutboundQueueSize < MAX_TOTAL_QUEUE_SIZE * 1.5) { this.TestReportPacketShouldDrop(packet); Interlocked.Add(ref _currentOutboundQueueSize, packet.DataSize); packet.AddRef(); queue.Enqueue(packet); } else { //this connection is in a pretty critical state and probably will never catch up. //drop all packets until we start to catch up. This includes acks which will disconnect //the client eventually anyways this.TestReportCriticalPacketDrop(packet); packet.DecRef(m_udpServer.ByteBufferPool); } } } else { Interlocked.Add(ref _currentOutboundQueueSize, packet.DataSize); packet.AddRef(); queue.Enqueue(packet); } return true; } else { // We don't have a token bucket for this category, so it will not be queued return false; } }
/// <summary> /// Add an unacked packet to the collection /// </summary> /// <param name="packet">Packet that is awaiting acknowledgement</param> /// <returns>True if the packet was successfully added, false if the /// packet already existed in the collection</returns> /// <remarks>This does not immediately add the ACK to the collection, /// it only queues it so it can be added in a thread-safe way later</remarks> public void Add(OutgoingPacket packet) { packet.AddRef(); m_pendingAdds.Enqueue(packet); }
public void AsyncBeginSend(OutgoingPacket packet) { if (!m_shutdownFlag) { try { packet.AddRef(); m_udpSocket.BeginSendTo( packet.Buffer.Data, 0, packet.DataSize, SocketFlags.None, packet.Destination, AsyncEndSend, packet); } catch (SocketException) { } catch (ObjectDisposedException) { } } }