diff --git a/server/src/sock/pool.hpp b/server/src/sock/pool.hpp index 5c37e53..1f9d805 100644 --- a/server/src/sock/pool.hpp +++ b/server/src/sock/pool.hpp @@ -34,10 +34,13 @@ public: void Start(); bool AddClient(T* client); int ClientCount() const; + inline bool IsOpen() const { + return this->is_open; + } void Stop(); protected: - virtual void ProcessClient(T* client) = 0; + virtual bool ProcessClient(T* client) = 0; private: class Stack { public: @@ -46,6 +49,9 @@ private: void AddClient(T* client); int ClientCount() const; + inline bool IsOpen() const { + return this->is_open; + } void Stop(); private: @@ -54,13 +60,15 @@ private: std::thread thread; Pool *pool; bool is_open; + bool is_running; std::list clients; std::mutex clients_mtx; }; poolinfo_t info; - bool is_running; + bool is_open; + std::vector stacks; friend class Stack; @@ -119,25 +127,64 @@ template Pool::Stack::Stack(Pool* pool) { this->pool = pool; this->is_open = false; + this->is_running = false; } template void Pool::Stack::Start() { - if(this->is_open) + if(this->is_open || this->is_running) return; - this->thread = std::thread(this->StackThread, this); this->is_open = true; + this->is_running = true; + this->thread = std::thread(this->StackThread, this); } template void Pool::Stack::AddClient(T* client) { + if(!this->is_open || !this->is_running) + return; + this->clients_mtx.lock(); + this->clients.push_back(client); + this->clients_mtx.unlock(); } template int Pool::Stack::ClientCount() const { + if(!this->is_open || !this->is_running) + return 0; + this->clients_mtx.lock(); + int count = this->clients.size(); + this->clients_mtx.unlock(); + + return count; +} + +template +void Pool::Stack::StackThread() { + while(this->is_running) { + for(auto i = this->clients.begin(); i != this->clients.end(); ++i) { + if(!this->is_running) + break; + + this->clients_mtx.lock(); + if(!this->pool->ProcessClient(*i)) + this->clients.erase(i); + this->clients_mtx.unlock(); + } + } +} + +template +void Pool::Stack::Stop() { + if(!this->is_open || !this->is_running) + return; + + this->is_running = false; + this->thread.join(); + this->is_open = false; } }