event_loop.h
namespace eventLoop {
class EventLoop {
public:
static std::unique_ptr<EventLoop> create();
~EventLoop();
void doShutDown();
bool onReceiveEvent(std::shared_ptr<std::string> event);
private:
EventLoop();
void receivingLoop();
void receiveEventLocked(std::unique_lock<std::mutex>& lock);
private:
std::deque<std::shared_ptr<std::string>> m_events;
bool m_is_shutdown;
std::mutex m_mutex;
std::condition_variable m_condition_variable;
std::thread m_receiving_thread;
};
}
event_loop.cpp
std::unique_ptr<eventLoop::EventLoop> eventLoop::EventLoop::create() {
return std::unique_ptr<eventLoop::EventLoop>(new eventLoop::EventLoop());
}
eventLoop::EventLoop::EventLoop()
: m_is_shutdown(false), m_mutex(), m_condition_variable() {
m_receiving_thread = std::thread(&eventLoop::EventLoop::receivingLoop, this);
}
eventLoop::EventLoop::~EventLoop() {
doShutDown();
}
void eventLoop::EventLoop::doShutDown() {
{
std::lock_guard<std::mutex> lock(m_mutex);
m_is_shutdown = true;
m_condition_variable.notify_one();
}
if (m_receiving_thread.joinable()) {
m_receiving_thread.join();
}
// other clear work
// ...
}
bool eventLoop::EventLoop::onReceiveEvent(std::shared_ptr<std::string> event) {
if (!event) {
return false;
}
std::lock_guard<std::mutex> lock(m_mutex);
if (m_is_shutdown) {
return false;
}
m_events.push_back(std::move(event));
m_condition_variable.notify_one();
}
void eventLoop::EventLoop::receivingLoop() {
auto wake = [this]() {
return !m_events.empty() || m_is_shutdown;
};
std::unique_lock<std::mutex> lock(m_mutex);
while (true) {
m_condition_variable.wait(lock, wake);
if (m_is_shutdown) {
break;
}
receiveEventLocked(lock);
}
}
void eventLoop::EventLoop::receiveEventLocked(std::unique_lock<std::mutex>& lock) {
if (m_events.empty()) {
return;
}
auto event = m_events.front();
m_events.pop_front();
lock.unlock();
// handle the event
// ...
std::cout << "handle the event->" << *event << std::endl;
lock.lock();
}