void event_loop::send_event(event_handler* handler, event_base* evt, bool deletable)
{
event_assert(handler);
event_assert(evt);
{
scoped_lock lock(sync_);
if (!handler->removing_) {
if (pending_events_.empty() && !active_handler_) {
cond_.signal(lock);
}
pending_events_.emplace_back(handler, evt, deletable);
return;
}
}
if (deletable) {
delete evt;
}
}
首先关注事件发送代码的函数 send_event() 及函数模版:
class FZ_PUBLIC_SYMBOL event_handler
{
......
template<typename T, typename... Args>
void send_event(Args&&... args) {
event_loop_.send_event(this, new T(std::forward<Args>(args)...), true);
}
template<typename T>
void send_event(T* evt) {
event_loop_.send_event(this, evt, true);
}
......
}
typedef simple_event<process_event_type, process*, process_event_flag> process_event;
......
void thread_entry()
{
......
if (h == ol_read_.hEvent) {
waiting_read_ = false;
handler_->send_event<process_event>(&process_, process_event_flag::read);
}
......
if (waiting_write_) {
waiting_write_ = false;
handler_->send_event<process_event>(&process_, process_event_flag::write);
}
......
}
......
这个类模版的作用是在调用时做如下展开:
handler_->send_event<process_event>(&process_, process_event_flag::read);
//展开调用为:
event_loop_.send_event(this, new process_event(&process_, process_event_flag::read), true);
那我们的核心问题是 handler_->send_event<process_event>(&process_, process_event_flag::read)
发出的事件,到底在哪里被执行?事件处理函数什么时候调用?
其次关注事件处理代码的函数 process_event() 及调用线程函数 entry():
void event_loop::entry()
{
thread_id_ = thread::own_id();
monotonic_clock now;
scoped_lock l(sync_);
while (!quit_) {
if (do_timers_ && process_timers(l, now)) {
continue;
}
if (process_event(l)) {
continue;
}
// Nothing to do, now we wait
cond_.wait(l);
}
}
在 process_event()中,从 send_event() 放进 event_loop::pending_events_ 中取出队列最前面的元祖 ev = pending_events_.front() 并执行元祖中重载的分发函数(这部分作者再用另一个博文讲解) (*std::get<0>(ev))(*std::get<1>(ev)) ,相当于 (*handler)(evt); // 实际调用事件处理函数 ,实际是调用 handler->operator()(evt) 。
// In event_loop.hpp
typedef std::deque<std::tuple<event_handler*, event_base*, bool>> Events;
// In event_loop.cpp
bool event_loop::process_event(scoped_lock & l)
{
Events::value_type ev{};
if (pending_events_.empty()) {
return false;
}
ev = pending_events_.front();
pending_events_.pop_front();
event_assert(std::get<0>(ev));
event_assert(std::get<1>(ev));
event_assert(!std::get<0>(ev)->removing_);
active_handler_ = std::get<0>(ev);
l.unlock();
event_assert(!resend_);
(*std::get<0>(ev))(*std::get<1>(ev));
if (resend_) {
resend_ = false;
l.lock();
if (!std::get<0>(ev)->removing_) {
pending_events_.emplace_back(ev);
}
else { // Unlikely, but possible to get into this branch branch
if (std::get<2>(ev)) {
delete std::get<1>(ev);
}
}
}
else {
if (std::get<2>(ev)) {
delete std::get<1>(ev);
}
l.lock();
}
active_handler_ = nullptr;
return true;
}
总结答案
事件处理(如 process_event
)的执行时机和位置如下:
-
由
event_loop::entry()
中的主循环触发 -
由
process_event()
从队列中取出并执行 -
实际调用的是
event_handler::operator()(event_base*)
虚函数 -
最终会触发
process_event::operator()(event_handler*)
的具体实现