#pragma once #include "Core.hpp" #include "Utilities.hpp" #include #include #include #include #include #include namespace reactor { class EventLoopThread : public NonCopyable { private: std::thread thread_; EventLoop* loop_; std::mutex mutex_; std::condition_variable cond_; std::string name_; void threadFunc() { LOG_DEBUG << "EventLoopThread '" << name_ << "' starting"; EventLoop loop; { std::lock_guard lock(mutex_); loop_ = &loop; cond_.notify_one(); } loop.loop(); std::lock_guard lock(mutex_); loop_ = nullptr; LOG_DEBUG << "EventLoopThread '" << name_ << "' finished"; } public: explicit EventLoopThread(const std::string& name = "EventLoopThread") : loop_(nullptr), name_(name) { thread_ = std::thread([this]() { threadFunc(); }); std::unique_lock lock(mutex_); cond_.wait(lock, [this]() { return loop_ != nullptr; }); LOG_INFO << "EventLoopThread '" << name_ << "' initialized"; } ~EventLoopThread() { if (loop_) { loop_->quit(); thread_.join(); } LOG_INFO << "EventLoopThread '" << name_ << "' destroyed"; } EventLoop* getLoop() { return loop_; } const std::string& name() const { return name_; } }; class EventLoopThreadPool : public NonCopyable { private: std::vector> threads_; std::vector loops_; std::atomic next_; std::string baseThreadName_; public: explicit EventLoopThreadPool(size_t numThreads, const std::string& baseName = "EventLoopThread") : next_(0), baseThreadName_(baseName) { LOG_INFO << "Creating EventLoopThreadPool with " << numThreads << " threads"; for (size_t i = 0; i < numThreads; ++i) { std::string threadName = baseThreadName_ + "-" + std::to_string(i); auto thread = std::make_unique(threadName); loops_.push_back(thread->getLoop()); threads_.push_back(std::move(thread)); } LOG_INFO << "EventLoopThreadPool created with " << numThreads << " threads"; } ~EventLoopThreadPool() { LOG_INFO << "EventLoopThreadPool destroying " << threads_.size() << " threads"; } EventLoop* getNextLoop() { if (loops_.empty()) { LOG_WARN << "EventLoopThreadPool has no loops available"; return nullptr; } size_t index = next_++ % loops_.size(); LOG_TRACE << "EventLoopThreadPool returning loop " << index; return loops_[index]; } std::vector getAllLoops() const { return loops_; } size_t size() const { return loops_.size(); } const std::string& getBaseName() const { return baseThreadName_; } }; } // namespace reactor