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