【Muduo源码剖析笔记】 网络库之EventLoop、Channel
EventLoop
声明了三个类,Channel、Poller和TimerQueue。
定义了Eventloop类。每个子线程拥有一个线程特有数据t_loopInThisThread,这是个Evenloop类型指针,子线程会在堆栈中创建new出自己对应的Eventloop对象,通过t_loopInThisThread这个指针访问和操作。
数据成员如下:
typedef std::function<void()> Functor;
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_);
定义了一个全局变量 __thread EventLoop* t_loopInThisThread = 0。每个线程都有这么一个Evenloop类型指针。
int createEventfd()
全局函数,创建一个非阻塞的文件,返回该文件描述符。
Class IgnoreSigPipe
对一个对端已经关闭的socket调用两次write, 第二次将会生成SIGPIPE信号, 该信号默认结束进程
定义了一个类,在namespace的命名空间,初始化函数会让遇到SIGPIPE信号的时候,执行SIG_IGN函数。
EventLoop::EventLoop()
将looping_置为false,quit_z置为false,eventHandling_置为false,iteration_初始化为0。
threadId_(CurrentThread::tid()),线程id会用CurrentThread中的tid函数返回。也就是这个构造函数会被子线程调用,应该是使用new。
poller_(Poller::newDefaultPoller(this)):
timerQueue_(new TimerQueue(this)):new一个新的指针初始化一个unique_ptr指针。
wakeupFd_(createEventfd()):创建一个新的文件描述符。
wakeupChannel_(new Channel(this, wakeupFd_)):会用刚刚创建新的文件描述符,初始化一个指向Channel类型的unique_ptr。
currentActiveChannel_(NULL):Channel类型的指针,置为NULL。
函数中会将EventLoop创建的信息写进LOG中(DEBUG级别)。
如果创建EventLoop这个线程是已经有t_loopInThisThread这个指针指向的数据的话,那么就会报LOG_FATAL级别的错误。
不然就将t_loopInThisThread指针指向现在正在创建的Eventloop。
给wakeupchannel设定回调函数,这个回调函数读wakeupFd_,获取一个文件描述符。
然后通过wakeupChannel_开启Reading模式。
~EventLoop()
会输出哪个线程的E