A lot of updates (Speed improvement)
This commit is contained in:
parent
2725c57f2e
commit
5842bbe067
@ -12,7 +12,7 @@
|
|||||||
#include <shared_mutex>
|
#include <shared_mutex>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring> /* for memset */
|
#include <cstring> /* for memset */
|
||||||
#include "./misc/spin_lock.h"
|
#include "misc/spin_mutex.h"
|
||||||
#include "Definitions.h"
|
#include "Definitions.h"
|
||||||
#include "Variable.h"
|
#include "Variable.h"
|
||||||
#include "spdlog/fmt/ostr.h" // must be included
|
#include "spdlog/fmt/ostr.h" // must be included
|
||||||
@ -894,7 +894,7 @@ namespace ts {
|
|||||||
bool requires_db_save = false;
|
bool requires_db_save = false;
|
||||||
ts_always_inline void trigger_db_update() { this->requires_db_save = true; }
|
ts_always_inline void trigger_db_update() { this->requires_db_save = true; }
|
||||||
|
|
||||||
spin_lock block_use_count_lock{};
|
spin_mutex block_use_count_lock{};
|
||||||
int16_t block_use_count[BULK_COUNT];
|
int16_t block_use_count[BULK_COUNT];
|
||||||
PermissionContainerBulk<PERMISSIONS_BULK_ENTRY_COUNT>* block_containers[BULK_COUNT];
|
PermissionContainerBulk<PERMISSIONS_BULK_ENTRY_COUNT>* block_containers[BULK_COUNT];
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ bool Properties::register_property_type(ts::property::PropertyType type, size_t
|
|||||||
for(int index = 0; index < bundle->length; index++) {
|
for(int index = 0; index < bundle->length; index++) {
|
||||||
auto& property = bundle->properties[index];
|
auto& property = bundle->properties[index];
|
||||||
property.value.~string();
|
property.value.~string();
|
||||||
property.value_lock.~spin_lock();
|
property.value_lock.~spin_mutex();
|
||||||
property.casted_value.~any();
|
property.casted_value.~any();
|
||||||
}
|
}
|
||||||
::free(bundle);
|
::free(bundle);
|
||||||
@ -104,7 +104,7 @@ bool Properties::register_property_type(ts::property::PropertyType type, size_t
|
|||||||
auto& property = ptr->properties[index];
|
auto& property = ptr->properties[index];
|
||||||
|
|
||||||
new (&property.casted_value) any();
|
new (&property.casted_value) any();
|
||||||
new (&property.value_lock) spin_lock();
|
new (&property.value_lock) spin_mutex();
|
||||||
new (&property.value) string();
|
new (&property.value) string();
|
||||||
property.description = &property::describe(type, index);
|
property.description = &property::describe(type, index);
|
||||||
property.flag_modified = false;
|
property.flag_modified = false;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#include <any>
|
#include <any>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "misc/spin_lock.h"
|
#include "misc/spin_mutex.h"
|
||||||
#include "converters/converter.h"
|
#include "converters/converter.h"
|
||||||
|
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
@ -684,7 +684,7 @@ namespace ts {
|
|||||||
class Properties;
|
class Properties;
|
||||||
|
|
||||||
struct PropertyData {
|
struct PropertyData {
|
||||||
spin_lock value_lock;
|
spin_mutex value_lock;
|
||||||
std::any casted_value;
|
std::any casted_value;
|
||||||
std::string value;
|
std::string value;
|
||||||
const property::PropertyDescription* description;
|
const property::PropertyDescription* description;
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#define always_inline inline __attribute__((__always_inline__))
|
#define always_inline inline __attribute__((__always_inline__))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class spin_lock {
|
class spin_mutex {
|
||||||
std::atomic_bool locked{false};
|
std::atomic_bool locked{false};
|
||||||
public:
|
public:
|
||||||
always_inline void lock() {
|
always_inline void lock() {
|
@ -33,22 +33,21 @@ size_t AcknowledgeManager::awaiting_acknowledge() {
|
|||||||
return this->entries.size();
|
return this->entries.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AcknowledgeManager::process_packet(ts::protocol::BasicPacket &packet) {
|
void AcknowledgeManager::process_packet(uint8_t type, uint32_t id, void *ptr, std::unique_ptr<threads::Future<bool>> ack) {
|
||||||
if(!packet.type().requireAcknowledge()) return;
|
std::shared_ptr<Entry> entry{new Entry{}, [&](Entry* entry){
|
||||||
|
this->destroy_packet(entry->packet_ptr);
|
||||||
|
delete entry;
|
||||||
|
}};
|
||||||
|
entry->acknowledge_listener = std::move(ack);
|
||||||
|
|
||||||
auto entry = make_shared<Entry>();
|
entry->packet_type = type;
|
||||||
entry->acknowledge_listener = std::move(packet.getListener());
|
entry->packet_full_id = id;
|
||||||
|
entry->packet_ptr = ptr;
|
||||||
entry->buffer = packet.buffer();
|
|
||||||
|
|
||||||
entry->resend_count = 0;
|
entry->resend_count = 0;
|
||||||
entry->first_send = system_clock::now();
|
entry->first_send = system_clock::now();
|
||||||
entry->next_resend = entry->first_send + std::chrono::milliseconds{(int64_t) ceil(this->rto)};
|
entry->next_resend = entry->first_send + std::chrono::milliseconds{(int64_t) ceil(this->rto)};
|
||||||
|
|
||||||
entry->packet_type = packet.type().type();
|
|
||||||
entry->packet_id = packet.packetId();
|
|
||||||
entry->generation_id = packet.generationId();
|
|
||||||
|
|
||||||
entry->acknowledged = false;
|
entry->acknowledged = false;
|
||||||
entry->send_count = 1;
|
entry->send_count = 1;
|
||||||
{
|
{
|
||||||
@ -65,7 +64,7 @@ bool AcknowledgeManager::process_acknowledge(uint8_t packet_type, uint16_t targe
|
|||||||
{
|
{
|
||||||
std::lock_guard lock{this->entry_lock};
|
std::lock_guard lock{this->entry_lock};
|
||||||
for(auto it = this->entries.begin(); it != this->entries.end(); it++) {
|
for(auto it = this->entries.begin(); it != this->entries.end(); it++) {
|
||||||
if((*it)->packet_type == target_type && (*it)->packet_id == target_id) {
|
if((*it)->packet_type == target_type && (*it)->packet_full_id == target_id) {
|
||||||
entry = *it;
|
entry = *it;
|
||||||
ack_listener = std::move(entry->acknowledge_listener); /* move it out so nobody else could call it as well */
|
ack_listener = std::move(entry->acknowledge_listener); /* move it out so nobody else could call it as well */
|
||||||
|
|
||||||
@ -110,7 +109,7 @@ ssize_t AcknowledgeManager::execute_resend(const system_clock::time_point& now ,
|
|||||||
if(entry->next_resend <= now) {
|
if(entry->next_resend <= now) {
|
||||||
entry->next_resend = now + std::chrono::milliseconds{(int64_t) std::min(ceil(this->rto), 1500.f)};
|
entry->next_resend = now + std::chrono::milliseconds{(int64_t) std::min(ceil(this->rto), 1500.f)};
|
||||||
need_resend.push_back(entry);
|
need_resend.push_back(entry);
|
||||||
entry->resend_count++;
|
//entry->resend_count++; /* this MUST be incremented by the result handler (resend may fails) */
|
||||||
entry->send_count++;
|
entry->send_count++;
|
||||||
}
|
}
|
||||||
if(next_resend > entry->next_resend)
|
if(next_resend > entry->next_resend)
|
||||||
@ -126,7 +125,7 @@ ssize_t AcknowledgeManager::execute_resend(const system_clock::time_point& now ,
|
|||||||
|
|
||||||
for(const auto& packet : need_resend) {
|
for(const auto& packet : need_resend) {
|
||||||
if(packet->resend_count > 15 && packet->first_send + seconds(15) < now) { //FIXME configurable
|
if(packet->resend_count > 15 && packet->first_send + seconds(15) < now) { //FIXME configurable
|
||||||
error = "Failed to receive acknowledge for packet " + to_string(packet->packet_id) + " of type " + PacketTypeInfo::fromid(packet->packet_type).name();
|
error = "Failed to receive acknowledge for packet " + to_string(packet->packet_full_id) + " of type " + PacketTypeInfo::fromid(packet->packet_type).name();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,22 +6,22 @@
|
|||||||
#define DEBUG_ACKNOWLEDGE
|
#define DEBUG_ACKNOWLEDGE
|
||||||
namespace ts::connection {
|
namespace ts::connection {
|
||||||
class VoiceClientConnection;
|
class VoiceClientConnection;
|
||||||
|
|
||||||
class AcknowledgeManager {
|
class AcknowledgeManager {
|
||||||
public:
|
public:
|
||||||
struct Entry {
|
struct Entry {
|
||||||
uint16_t packet_id{0};
|
uint32_t packet_full_id{0};
|
||||||
uint16_t generation_id{0};
|
|
||||||
|
|
||||||
uint8_t packet_type{0xFF};
|
uint8_t packet_type{0xFF};
|
||||||
|
|
||||||
uint8_t resend_count{0};
|
uint8_t resend_count{0};
|
||||||
bool acknowledged : 1;
|
bool acknowledged : 1;
|
||||||
uint8_t send_count : 7;
|
uint8_t send_count : 7;
|
||||||
|
|
||||||
|
|
||||||
pipes::buffer buffer;
|
|
||||||
std::chrono::system_clock::time_point first_send;
|
std::chrono::system_clock::time_point first_send;
|
||||||
std::chrono::system_clock::time_point next_resend;
|
std::chrono::system_clock::time_point next_resend;
|
||||||
std::unique_ptr<threads::Future<bool>> acknowledge_listener;
|
std::unique_ptr<threads::Future<bool>> acknowledge_listener;
|
||||||
|
|
||||||
|
void* packet_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
AcknowledgeManager();
|
AcknowledgeManager();
|
||||||
@ -30,8 +30,8 @@ namespace ts::connection {
|
|||||||
size_t awaiting_acknowledge();
|
size_t awaiting_acknowledge();
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
void process_packet(ts::protocol::BasicPacket& /* packet */);
|
void process_packet(uint8_t /* packet type */, uint32_t /* full packet id */, void* /* packet ptr */, std::unique_ptr<threads::Future<bool>> /* ack listener */);
|
||||||
bool process_acknowledge(uint8_t packet_type, uint16_t /* packet id */, std::string& /* error */);
|
bool process_acknowledge(uint8_t /* packet type */, uint16_t /* packet id */, std::string& /* error */);
|
||||||
|
|
||||||
ssize_t execute_resend(
|
ssize_t execute_resend(
|
||||||
const std::chrono::system_clock::time_point& /* now */,
|
const std::chrono::system_clock::time_point& /* now */,
|
||||||
@ -43,6 +43,8 @@ namespace ts::connection {
|
|||||||
[[nodiscard]] inline auto current_rto() const { return this->rto; }
|
[[nodiscard]] inline auto current_rto() const { return this->rto; }
|
||||||
[[nodiscard]] inline auto current_srtt() const { return this->srtt; }
|
[[nodiscard]] inline auto current_srtt() const { return this->srtt; }
|
||||||
[[nodiscard]] inline auto current_rttvar() const { return this->rttvar; }
|
[[nodiscard]] inline auto current_rttvar() const { return this->rttvar; }
|
||||||
|
|
||||||
|
void(*destroy_packet)(void* /* packet */);
|
||||||
private:
|
private:
|
||||||
std::mutex entry_lock;
|
std::mutex entry_lock;
|
||||||
std::deque<std::shared_ptr<Entry>> entries;
|
std::deque<std::shared_ptr<Entry>> entries;
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
#include <src/misc/spin_mutex.h>
|
||||||
#include "Packet.h"
|
#include "Packet.h"
|
||||||
#include "buffers.h"
|
#include "buffers.h"
|
||||||
#include "misc/endianness.h"
|
#include "misc/endianness.h"
|
||||||
@ -244,4 +245,139 @@ namespace ts {
|
|||||||
uint8_t ServerPacketParser::type() const { return (uint8_t) this->_buffer[ClientPacketParser::kHeaderOffset + 2] & 0xFU; }
|
uint8_t ServerPacketParser::type() const { return (uint8_t) this->_buffer[ClientPacketParser::kHeaderOffset + 2] & 0xFU; }
|
||||||
uint8_t ServerPacketParser::flags() const { return (uint8_t) this->_buffer[ClientPacketParser::kHeaderOffset + 2] & 0xF0U; }
|
uint8_t ServerPacketParser::flags() const { return (uint8_t) this->_buffer[ClientPacketParser::kHeaderOffset + 2] & 0xF0U; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void construct_osp(protocol::OutgoingServerPacket* packet) {
|
||||||
|
new (&packet->ref_count) std::atomic<uint16_t>{};
|
||||||
|
}
|
||||||
|
|
||||||
|
void deconstruct_osp(protocol::OutgoingServerPacket* packet) {
|
||||||
|
packet->ref_count.~atomic<uint16_t>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset_osp(protocol::OutgoingServerPacket* packet, size_t payload_size) {
|
||||||
|
packet->next = nullptr;
|
||||||
|
packet->payload_size = payload_size;
|
||||||
|
|
||||||
|
packet->generation = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
#define BUKKIT_ENTRY_SIZE (1650)
|
||||||
|
#define BUKKIT_MAX_ENTRIES (3000)
|
||||||
|
|
||||||
|
struct OSPBukkitEntry {
|
||||||
|
bool extra_allocated;
|
||||||
|
OSPBukkitEntry* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
spin_mutex osp_mutex{};
|
||||||
|
size_t sdp_count{0};
|
||||||
|
OSPBukkitEntry* osp_head{nullptr};
|
||||||
|
OSPBukkitEntry** osp_tail{&osp_head};
|
||||||
|
|
||||||
|
protocol::OutgoingServerPacket* osp_from_bosp(OSPBukkitEntry* bops) {
|
||||||
|
return reinterpret_cast<protocol::OutgoingServerPacket*>((char*) bops + sizeof(OSPBukkitEntry));
|
||||||
|
}
|
||||||
|
|
||||||
|
OSPBukkitEntry* bosp_from_osp(protocol::OutgoingServerPacket* ops) {
|
||||||
|
return reinterpret_cast<OSPBukkitEntry*>((char*) ops - sizeof(OSPBukkitEntry));
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy_bosp(OSPBukkitEntry* entry) {
|
||||||
|
deconstruct_osp(osp_from_bosp(entry));
|
||||||
|
::free(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
OSPBukkitEntry* construct_bosp(size_t payload_size) {
|
||||||
|
auto base_size = sizeof(OSPBukkitEntry) + sizeof(protocol::OutgoingServerPacket) - 1;
|
||||||
|
auto full_size = base_size + payload_size;
|
||||||
|
auto bentry = (OSPBukkitEntry*) malloc(full_size);
|
||||||
|
|
||||||
|
bentry->next = nullptr;
|
||||||
|
bentry->extra_allocated = false;
|
||||||
|
|
||||||
|
construct_osp(osp_from_bosp(bentry));
|
||||||
|
return bentry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void protocol::OutgoingServerPacket::object_freed() {
|
||||||
|
auto bentry = (OSPBukkitEntry*) bosp_from_osp(this);
|
||||||
|
if(bentry->extra_allocated) {
|
||||||
|
destroy_bosp(bentry);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_lock block{osp_mutex};
|
||||||
|
if(sdp_count >= BUKKIT_MAX_ENTRIES) {
|
||||||
|
block.unlock();
|
||||||
|
destroy_bosp(bentry);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(!bentry->next);
|
||||||
|
*osp_tail = bentry;
|
||||||
|
osp_tail = &bentry->next;
|
||||||
|
sdp_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol::OutgoingServerPacket* protocol::allocate_outgoing_packet(size_t payload_size) {
|
||||||
|
if(BUKKIT_ENTRY_SIZE > payload_size) {
|
||||||
|
std::lock_guard block{osp_mutex};
|
||||||
|
if(osp_head) {
|
||||||
|
assert(sdp_count > 0);
|
||||||
|
sdp_count--;
|
||||||
|
auto entry = osp_head;
|
||||||
|
if(osp_head->next) {
|
||||||
|
assert(osp_tail != &osp_head->next);
|
||||||
|
osp_head = osp_head->next;
|
||||||
|
} else {
|
||||||
|
assert(osp_tail == &osp_head->next);
|
||||||
|
osp_head = nullptr;
|
||||||
|
osp_tail = &osp_head;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry->next = nullptr;
|
||||||
|
|
||||||
|
auto result = osp_from_bosp(entry);
|
||||||
|
reset_osp(result, payload_size);
|
||||||
|
result->ref_count++;
|
||||||
|
return result;
|
||||||
|
} else if(sdp_count < BUKKIT_MAX_ENTRIES) {
|
||||||
|
auto entry = construct_bosp(BUKKIT_ENTRY_SIZE);
|
||||||
|
entry->extra_allocated = false;
|
||||||
|
|
||||||
|
auto result = osp_from_bosp(entry);
|
||||||
|
reset_osp(result, payload_size);
|
||||||
|
result->ref_count++;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto entry = construct_bosp(payload_size);
|
||||||
|
entry->extra_allocated = true;
|
||||||
|
|
||||||
|
auto result = osp_from_bosp(entry);
|
||||||
|
reset_osp(result, payload_size);
|
||||||
|
result->ref_count++;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void protocol::OutgoingServerPacket::object_freed() {
|
||||||
|
//TODO: Bukkit list?
|
||||||
|
deconstruct_osp(this);
|
||||||
|
::free(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol::OutgoingServerPacket* protocol::allocate_outgoing_packet(size_t payload_size) {
|
||||||
|
auto base_size = sizeof(protocol::OutgoingServerPacket) - 1;
|
||||||
|
auto full_size = base_size + payload_size;
|
||||||
|
auto result = (protocol::OutgoingServerPacket*) malloc(full_size);
|
||||||
|
|
||||||
|
construct_osp(result);
|
||||||
|
reset_osp(result, payload_size);
|
||||||
|
result->ref_count++;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
@ -75,37 +75,37 @@ namespace ts {
|
|||||||
bool owns_data = false;
|
bool owns_data = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PacketIdManagerData {
|
|
||||||
PacketIdManagerData(){
|
|
||||||
memset(this->packetCounter, 0, sizeof(uint32_t) * 16);
|
|
||||||
}
|
|
||||||
uint32_t packetCounter[16]{};
|
|
||||||
};
|
|
||||||
|
|
||||||
class PacketIdManager {
|
class PacketIdManager {
|
||||||
public:
|
public:
|
||||||
PacketIdManager() : data(new PacketIdManagerData){}
|
PacketIdManager() {
|
||||||
|
this->reset();
|
||||||
|
}
|
||||||
|
|
||||||
~PacketIdManager() = default;
|
~PacketIdManager() = default;
|
||||||
PacketIdManager(const PacketIdManager& ref) : data(ref.data) {}
|
PacketIdManager(const PacketIdManager& ref) = delete;
|
||||||
PacketIdManager(PacketIdManager&& ref) : data(std::move(ref.data)) {}
|
PacketIdManager(PacketIdManager&& ref) = delete;
|
||||||
|
|
||||||
uint16_t nextPacketId(const PacketTypeInfo &type){
|
[[nodiscard]] uint16_t nextPacketId(const PacketTypeInfo &type){
|
||||||
return static_cast<uint16_t>(data->packetCounter[type.type()]++ & 0xFFFF);
|
return static_cast<uint16_t>(this->packetCounter[type.type()]++ & 0xFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t currentPacketId(const PacketTypeInfo &type){
|
[[nodiscard]] uint16_t currentPacketId(const PacketTypeInfo &type){
|
||||||
return static_cast<uint16_t>(data->packetCounter[type.type()] & 0xFFFF);
|
return static_cast<uint16_t>(this->packetCounter[type.type()] & 0xFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t generationId(const PacketTypeInfo &type){
|
[[nodiscard]] uint16_t generationId(const PacketTypeInfo &type){
|
||||||
return static_cast<uint16_t>((data->packetCounter[type.type()] >> 16) & 0xFFFF);
|
return static_cast<uint16_t>((this->packetCounter[type.type()] >> 16) & 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] uint32_t generate_full_id(const PacketType& type) {
|
||||||
|
return this->packetCounter[type]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
memset(&data->packetCounter[0], 0, sizeof(uint32_t) * 16);
|
memset(&this->packetCounter[0], 0, sizeof(uint32_t) * 16);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<PacketIdManagerData> data;
|
uint32_t packetCounter[16]{};
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace PacketFlag {
|
namespace PacketFlag {
|
||||||
@ -383,12 +383,16 @@ namespace ts {
|
|||||||
void setPacketId(uint16_t, uint16_t) override;
|
void setPacketId(uint16_t, uint16_t) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ServerPacketParser : public PacketParser {
|
class ServerPacketP {
|
||||||
public:
|
public:
|
||||||
constexpr static auto kHeaderOffset = 8;
|
constexpr static auto kHeaderOffset = 8;
|
||||||
constexpr static auto kHeaderLength = SERVER_HEADER_SIZE;
|
constexpr static auto kHeaderLength = SERVER_HEADER_SIZE;
|
||||||
|
|
||||||
constexpr static auto kPayloadOffset = kHeaderOffset + SERVER_HEADER_SIZE;
|
constexpr static auto kPayloadOffset = kHeaderOffset + SERVER_HEADER_SIZE;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ServerPacketParser : public PacketParser, public ServerPacketP {
|
||||||
|
public:
|
||||||
explicit ServerPacketParser(pipes::buffer_view buffer) : PacketParser{std::move(buffer)} {}
|
explicit ServerPacketParser(pipes::buffer_view buffer) : PacketParser{std::move(buffer)} {}
|
||||||
ServerPacketParser(const ServerPacketParser&) = delete;
|
ServerPacketParser(const ServerPacketParser&) = delete;
|
||||||
|
|
||||||
@ -404,5 +408,59 @@ namespace ts {
|
|||||||
[[nodiscard]] uint8_t type() const override;
|
[[nodiscard]] uint8_t type() const override;
|
||||||
[[nodiscard]] uint8_t flags() const override;
|
[[nodiscard]] uint8_t flags() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct OutgoingServerPacket {
|
||||||
|
public:
|
||||||
|
/* general info */
|
||||||
|
std::atomic<uint16_t> ref_count;
|
||||||
|
size_t payload_size;
|
||||||
|
|
||||||
|
OutgoingServerPacket* next; /* used within the write/process queue */
|
||||||
|
uint16_t generation;
|
||||||
|
|
||||||
|
/* actual packet data */
|
||||||
|
uint8_t mac[8];
|
||||||
|
uint8_t packet_id_bytes[2];
|
||||||
|
uint8_t type_and_flags;
|
||||||
|
uint8_t payload[1]; /* variable size */
|
||||||
|
|
||||||
|
[[nodiscard]] inline const void* packet_data() const {
|
||||||
|
return this->mac;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline size_t packet_length() const {
|
||||||
|
return this->payload_size + (8 + 2 + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto ref() {
|
||||||
|
auto count = ++ref_count;
|
||||||
|
assert(count > 1);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void unref() {
|
||||||
|
if(--this->ref_count == 0)
|
||||||
|
this->object_freed();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* some helper methods */
|
||||||
|
inline void set_packet_id(uint16_t id) {
|
||||||
|
this->packet_id_bytes[0] = id >> 8U;
|
||||||
|
this->packet_id_bytes[1] = id & 0xFFU;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline auto packet_id() const {
|
||||||
|
return (uint16_t) (this->packet_id_bytes[0] << 8U) | this->packet_id_bytes[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline auto packet_type() const {
|
||||||
|
return (PacketType) (this->type_and_flags & 0xF);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
void object_freed();
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This will allocate a new outgoing packet. To delete just unref the packet! */
|
||||||
|
OutgoingServerPacket* allocate_outgoing_packet(size_t /* payload size */);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,7 +6,7 @@
|
|||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include "sql/SqlQuery.h"
|
#include "sql/SqlQuery.h"
|
||||||
|
|
||||||
#include "../../misc/spin_lock.h"
|
#include "misc/spin_mutex.h"
|
||||||
|
|
||||||
#if defined(HAVE_MYSQL_MYSQL_H)
|
#if defined(HAVE_MYSQL_MYSQL_H)
|
||||||
#include <mysql/mysql.h>
|
#include <mysql/mysql.h>
|
||||||
@ -31,7 +31,7 @@ namespace sql::mysql {
|
|||||||
struct Connection {
|
struct Connection {
|
||||||
MYSQL* handle = nullptr;
|
MYSQL* handle = nullptr;
|
||||||
|
|
||||||
spin_lock used_lock;
|
spin_mutex used_lock;
|
||||||
bool used = false;
|
bool used = false;
|
||||||
|
|
||||||
~Connection();
|
~Connection();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user