-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEventLoop.h
More file actions
108 lines (88 loc) · 2.78 KB
/
Copy pathEventLoop.h
File metadata and controls
108 lines (88 loc) · 2.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#ifndef EVENTLOOP_H
#define EVENTLOOP_H
/**
* 线程通信机制:
* #include <sys/eventfd.h>
int eventfd(unsigned int initval, int flags);
* 通过内核通知来传递信息 使得线程之间通信
优点:高性能 缺点:不可跨平台
* #include <sys/socket.h>
int socketpair(int domain, int type, int protocol, int sv[2]);
通过网络socket传递信息 使得两线程通信 sv[0]与sv[1]通信
*/
#include "noncopyable.h"
#include "Timestamp.h"
#include "CurrentThread.h"
#include <functional>
#include <atomic>
#include <memory>
#include <mutex>
#include<vector>
class Channel;
class Poller;
/***
* EventLoop
* ChannelList poller
* epollpoller (extend pollpoller selectpoller...) (channelList conut >= channelmap)
* channelMap <fd,channel*>
*
*/
class EventLoop : noncopyable
{
public:
using Functor = std::function<void()>;
// 开启事件循环
void loop();
// 退出事件循环
void quit();
// 在当前线程执行cb
void runInLoop(Functor cb);
// 投递给任务队列 唤醒loop所在线程 暂不执行cb
void queueInLoop(Functor cb);
// 唤醒loop所在线程
void weakup();
// EventLoop -> poller
void updateChannel(Channel *channel);
void removeChannel(Channel *channel);
bool hasChannel(Channel *target) const;
// 判断当前loop对象是否在自己线程
bool isInLoopThread() { return threadId_ == CurrentThread::tid(); }
EventLoop(/* args */);
~EventLoop();
private:
/* data */
using ChannelList = std::vector<Channel *>;
/*EventLoop 是否正在运行*/
std::atomic_bool looping_;
// EventLoop 是否退出
std::atomic_bool quit_;
// 当前loop 的线程id
const pid_t threadId_;
// eventLoop的调度器
std::unique_ptr<Poller> poller_;
// poller所返回的事件集合的时间
Timestamp pollerRetTime_;
/**线程通信
* 当main eventloop 负责监听到一个新的accept时 包装成channel,传递给工作线程。
* 为什么需要线程通信?
* 当main loop和work loop 空闲时让它们线程挂起不占用cpu资源,需要时唤醒
*/
// 轮询选择work loop
int weakupFd_;
// 当前的channel
std::unique_ptr<Channel> weakupChannel_;
/** 存储所有event loop all channel channel的集合*/
ChannelList activeChannels_;
Channel *currentActiveChannel_;
/**当前event loop 是否需要执行回调函数*/
std::atomic_bool callingPendingFunctor_;
// 存储所有回调函数
std::vector<Functor> pendingFunctors_;
// 互斥回调函数
std::mutex mtx_;
// weakup
void handleRead();
// 执行回调
void doPendingFunctor();
};
#endif