介绍:EventLoop是初始分发器,其实就是一个reactor角色。它本身定义了一些规范,这些规范用于控制事件的调度方式,同时又提供了应用进行事件处理器的注册、删除等设施。它本身是整个事件处理器的核心所在,初始分发器会通过同步事件分离器来等待事件的发生。一旦事件发生,初始分发器首先会分离出每一个事件,然后调用事件处理器,最后调用相关的回调方法来处理这些事件。
1.EventLoop.h文件
///一个线程只能拥有一个reactor
class EventLoop : noncopyable
{
public:
typedef std::function<void()> Functor;
EventLoop();
~EventLoop();
///调用这个函数,开始循环等待事件发生
void loop();
///退出循环等待
void quit();
///监听事件发生了的时间
Timestamp pollReturnTime() const { return pollReturnTime_; }
int64_t iteration() const { return iteration_; }
///在loop线程立即调用,不是的话加加入到pendingFunctors_中去,等待调用
void runInLoop(Functor cb);
///不在该线程时,runInLoop会调用queueInLoop
void queueInLoop(Functor cb);
///返回队列中还有几个待执行的函数
size_t queueSize() const;
/// Runs callback at 'time'.
TimerId runAt(Timestamp time, TimerCallback cb);
TimerId runAfter(double delay, TimerCallback cb);
TimerId runEvery(double interval, TimerCallback cb);
void cancel(TimerId timerId);
// 内部调用
void wakeup(); ///唤醒当前线程
void updateChannel(Channel* channel); ///更新通道状态
void removeChannel(Channel* channel); ///移除监听通道
bool hasChannel(Channel* channel); ///channel是否在ChannelMap(poller的内容)中
// pid_t threadId() const { return threadId_; }
///不在此对象的线程的话,就打印当前线程的id和此对象所在的线程id
void assertInLoopThread()
{
if (!isInLoopThread()) ///判断是否在此对象的线程
{
abortNotInLoopThread(); ///
}
}
///判断是否在该对象的线程中
bool isInLoopThread() const { return threadId_ == CurrentThread::tid(); }
// bool callingPendingFunctors() const { return callingPendingFunctors_; }
///返回currentActiveChannel是否在调用监听到事件对应的该执行的回调函数
bool eventHandling() const { return eventHandling_; }
void setContext(const boost::any& context)
{ context_ = context; }
const boost::any& getContext() const
{ return context_; }
boost::any* getMutableContext()
{ return &context_; }
static EventLoop* getEventLoopOfCurrentThread();
private:
void abortNotInLoopThread();
void handleRead(); // waked up
void doPendingFunctors();
void printActiveChannels() const; // DEBUG
typedef std::vector<Channel*> ChannelList;
bool looping_; /* atomic */
std::atomic<bool> quit_;
bool eventHandling_; /* atomic */
bool callingPendingFunctors_; /* atomic */
int64_t iteration_;
const pid_t threadId_;
Timestamp pollReturnTime_;
std::unique_ptr<Poller> poller_;
std::unique_ptr<TimerQueue> timerQueue_;
int wakeupFd_;
// unlike in TimerQueue, which is an internal class,
// we don't expose Channel to client.
std::unique_ptr<Channel> wakeupChannel_;
boost::any context_;
// scratch variables
ChannelList activeChannels_;
Channel* currentActiveChannel_;
mutable MutexLock mutex_;
std::vector<Functor> pendingFunctors_ GUARDED_BY(mutex_);
};