#pragma once #include #include #include "client/voice/PrecomputedPuzzles.h" #include "server/VoiceIOManager.h" #include "TSServer.h" namespace ts { namespace server { class InstanceHandler; struct ServerReport { size_t avariable; size_t online; size_t slots; size_t onlineClients; size_t onlineChannels; }; class ServerManager { public: enum State { STOPPED, STARTING, STARTED, STOPPING }; explicit ServerManager(InstanceHandler*); ~ServerManager(); bool initialize(bool execute_autostart = true); std::shared_ptr createServer(std::string, uint16_t); bool deleteServer(std::shared_ptr); std::shared_ptr findServerById(ServerId); std::shared_ptr findServerByPort(uint16_t); uint16_t next_available_port(); ServerId next_available_server_id(bool& /* success */); std::deque> serverInstances(){ threads::MutexLock l(this->instanceLock); return instances; } ServerReport report(); OnlineClientReport clientReport(); size_t runningServers(); size_t usedSlots(); void executeAutostart(); void shutdownAll(const std::string&); //Dotn use shared_ptr references to keep sure that they be hold in memory bool createServerSnapshot(Command &cmd, std::shared_ptr server, int version, std::string &error); std::shared_ptr createServerFromSnapshot(std::shared_ptr old, std::string, uint16_t, const ts::Command &, std::string &); size_t maxSlotLimit(){ return 254; } protocol::PuzzleManager* rsaPuzzles() { return this->puzzles; } event::EventExecutor* get_join_loop() { return this->join_loop; } event::EventExecutor* get_executor_loop() { return this->execute_loop; } inline void adjust_executor_threads() { std::unique_lock instance_lock(this->instanceLock); auto instance_count = this->instances.size(); instance_lock.unlock(); auto threads = std::min(config::threads::voice::execute_per_server * instance_count, config::threads::voice::execute_limit); this->execute_loop->threads(threads); } io::VoiceIOManager* ioManager(){ return this->_ioManager; } threads::Mutex server_create_lock; State getState() { return this->state; } private: State state = State::STOPPED; InstanceHandler* handle; threads::Mutex instanceLock; std::deque> instances; protocol::PuzzleManager* puzzles = nullptr; event::EventExecutor* execute_loop = nullptr; event::EventExecutor* join_loop = nullptr; threads::Scheduler* handshakeTickers = nullptr; io::VoiceIOManager* _ioManager = nullptr; struct { threads::Thread* thread = nullptr; std::condition_variable condition; std::mutex lock; } acknowledge; void tickHandshakeClients(); }; } }