forked from Mirrorlandia_minetest/minetest
007ce24a11
* Optimize packet construction functions Some of the functions that construct packets in connection.cpp are using a const reference to get the raw packet data to package and others use a value passed parameter to do that. The ones that use the value passed parameter suffer from performance hit as the rather bulky packet data gets a temporary copy when the parameter is passed before it lands at its final destination inside the newly constructed packet. The unnecessary temporary copy hurts quite badly as the underlying class (SharedBuffer) actually allocates the space for the data in the heap. Fix the performance hit by converting all of these value passed parameters to const references. I believe that this is what the author of the relevant code actually intended to do as there is a couple of packet construction helper functions that already use a const reference to get the raw data. * Optimize packet sender thread class Most of the data sending methods of the packet sender thread class use a value passed parameter for the packet data to be sent. This causes the rather bulky data to be allocated on the heap and copied, slowing the packet sending down. Convert these parameters to const references to avoid the performance hit. * Optimize packet receiver thread class The packet receiver and processor thread class has many methods (mostly packet handlers) that receive the packed data by value. This causes a performance hit that is actually worse than the one caused by the packet sender methods because the packet is first handed to the processPacket method which looks at the packet type stored in the header and then delegates the actual handling to one of the handlers. Both, processPacket and all the handlers get the packet data by value, leading to at least two unnecessary copies of the data (with malloc and all the slow bells and whistles of bulky classes). As there already is a few methods that use a const reference parameter for the packet data, convert all this value passed packets to const references.
151 lines
4.4 KiB
C++
151 lines
4.4 KiB
C++
/*
|
|
Minetest
|
|
Copyright (C) 2013-2017 celeron55, Perttu Ahola <celeron55@gmail.com>
|
|
Copyright (C) 2017 celeron55, Loic Blot <loic.blot@unix-experience.fr>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation; either version 2.1 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License along
|
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <cassert>
|
|
#include "threading/thread.h"
|
|
#include "connection.h"
|
|
|
|
namespace con
|
|
{
|
|
|
|
class Connection;
|
|
|
|
class ConnectionSendThread : public Thread
|
|
{
|
|
|
|
public:
|
|
friend class UDPPeer;
|
|
|
|
ConnectionSendThread(unsigned int max_packet_size, float timeout);
|
|
|
|
void *run();
|
|
|
|
void Trigger();
|
|
|
|
void setParent(Connection *parent)
|
|
{
|
|
assert(parent != NULL); // Pre-condition
|
|
m_connection = parent;
|
|
}
|
|
|
|
void setPeerTimeout(float peer_timeout) { m_timeout = peer_timeout; }
|
|
|
|
private:
|
|
void runTimeouts(float dtime);
|
|
void rawSend(const BufferedPacket &packet);
|
|
bool rawSendAsPacket(session_t peer_id, u8 channelnum,
|
|
const SharedBuffer<u8> &data, bool reliable);
|
|
|
|
void processReliableCommand(ConnectionCommand &c);
|
|
void processNonReliableCommand(ConnectionCommand &c);
|
|
void serve(Address bind_address);
|
|
void connect(Address address);
|
|
void disconnect();
|
|
void disconnect_peer(session_t peer_id);
|
|
void send(session_t peer_id, u8 channelnum, const SharedBuffer<u8> &data);
|
|
void sendReliable(ConnectionCommand &c);
|
|
void sendToAll(u8 channelnum, const SharedBuffer<u8> &data);
|
|
void sendToAllReliable(ConnectionCommand &c);
|
|
|
|
void sendPackets(float dtime);
|
|
|
|
void sendAsPacket(session_t peer_id, u8 channelnum, const SharedBuffer<u8> &data,
|
|
bool ack = false);
|
|
|
|
void sendAsPacketReliable(BufferedPacket &p, Channel *channel);
|
|
|
|
bool packetsQueued();
|
|
|
|
Connection *m_connection = nullptr;
|
|
unsigned int m_max_packet_size;
|
|
float m_timeout;
|
|
std::queue<OutgoingPacket> m_outgoing_queue;
|
|
Semaphore m_send_sleep_semaphore;
|
|
|
|
unsigned int m_iteration_packets_avaialble;
|
|
unsigned int m_max_commands_per_iteration = 1;
|
|
unsigned int m_max_data_packets_per_iteration;
|
|
unsigned int m_max_packets_requeued = 256;
|
|
};
|
|
|
|
class ConnectionReceiveThread : public Thread
|
|
{
|
|
public:
|
|
ConnectionReceiveThread(unsigned int max_packet_size);
|
|
|
|
void *run();
|
|
|
|
void setParent(Connection *parent)
|
|
{
|
|
assert(parent); // Pre-condition
|
|
m_connection = parent;
|
|
}
|
|
|
|
private:
|
|
void receive();
|
|
|
|
// Returns next data from a buffer if possible
|
|
// If found, returns true; if not, false.
|
|
// If found, sets peer_id and dst
|
|
bool getFromBuffers(session_t &peer_id, SharedBuffer<u8> &dst);
|
|
|
|
bool checkIncomingBuffers(
|
|
Channel *channel, session_t &peer_id, SharedBuffer<u8> &dst);
|
|
|
|
/*
|
|
Processes a packet with the basic header stripped out.
|
|
Parameters:
|
|
packetdata: Data in packet (with no base headers)
|
|
peer_id: peer id of the sender of the packet in question
|
|
channelnum: channel on which the packet was sent
|
|
reliable: true if recursing into a reliable packet
|
|
*/
|
|
SharedBuffer<u8> processPacket(Channel *channel,
|
|
const SharedBuffer<u8> &packetdata, session_t peer_id,
|
|
u8 channelnum, bool reliable);
|
|
|
|
SharedBuffer<u8> handlePacketType_Control(Channel *channel,
|
|
const SharedBuffer<u8> &packetdata, Peer *peer, u8 channelnum,
|
|
bool reliable);
|
|
SharedBuffer<u8> handlePacketType_Original(Channel *channel,
|
|
const SharedBuffer<u8> &packetdata, Peer *peer, u8 channelnum,
|
|
bool reliable);
|
|
SharedBuffer<u8> handlePacketType_Split(Channel *channel,
|
|
const SharedBuffer<u8> &packetdata, Peer *peer, u8 channelnum,
|
|
bool reliable);
|
|
SharedBuffer<u8> handlePacketType_Reliable(Channel *channel,
|
|
const SharedBuffer<u8> &packetdata, Peer *peer, u8 channelnum,
|
|
bool reliable);
|
|
|
|
struct PacketTypeHandler
|
|
{
|
|
SharedBuffer<u8> (ConnectionReceiveThread::*handler)(Channel *channel,
|
|
const SharedBuffer<u8> &packet, Peer *peer, u8 channelnum,
|
|
bool reliable);
|
|
};
|
|
|
|
static const PacketTypeHandler packetTypeRouter[PACKET_TYPE_MAX];
|
|
|
|
Connection *m_connection = nullptr;
|
|
};
|
|
}
|