Looper就是对epoll系统调用的封装层,屏蔽外部对epoll的直接使用
sequenceDiagram
rect rgb(199, 237, 204)
Looper->>Looper: Looper()
activate Looper
Looper->>Looper: mWakeEventFd = eventfd
Looper->>Looper: rebuildEpollLocked
activate Looper
Looper->>Looper: mEpollFd = epoll_create(EPOLL_SIZE_HINT)
Note right of Looper: eventItem.events = EPOLLIN,eventItem.data.fd = mWakeEventFd
Looper->>Looper: epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeEventFd, & eventItem)
Note right of Looper: 编译mRequests对每个子项进行下面的ctl,mRequests通过addFd添加元素
Looper->>Looper: epoll_ctl(mEpollFd, EPOLL_CTL_ADD, request.fd, & eventItem)
deactivate Looper
deactivate Looper
end
rect rgb(199, 237, 204)
Looper->>Looper: addFd
Note right of Looper: 将fd封装成request,epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, &eventItem),use SimpleLooperCallback as adapter from handleEvent to callback function
end
rect rgb(199, 237, 204)
Looper->>Looper: pollOnce,开启for循环
activate Looper
Note right of Looper: timeoutMillis由MessageQueue的next()方法提供,队列中有message时,时间为msg.when-now,否则无消息,为-1表示一直在epoll中等待消息
Looper->>Looper: 处理mResponses并尝试return
Looper->>Looper: pollInner
activate Looper
Looper->>Looper: int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis)
Looper->>Looper: 针对eventCount中每个event,if(fd == mWakeEventFd && epollEvents & EPOLLIN)awoken(),否则对应到mRequests中并pushResponse
Looper->>Looper: 1:处理mMessageEnvelopes中的C层消息
Looper->>Looper: 2:处理mResponses中元素,回调通过addFd添加进来的监听
Looper->>Looper: 3:返回之后回到java层的循环处处理java层消息
deactivate Looper
deactivate Looper
end
system/core/libutils/Looper.cpp
Looper::Looper(bool allowNonCallbacks) :
mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false),
mPolling(false), mEpollFd(-1), mEpollRebuildRequired(false),
mNextRequestSeq(0), mResponseIndex(0), mNextMessageUptime(LLONG_MAX) {
mWakeEventFd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);//main
LOG_ALWAYS_FATAL_IF(mWakeEventFd < 0, "Could not make wake event fd: %s",
strerror(errno));
AutoMutex _l(mLock);
rebuildEpollLocked();//main
}
void Looper::rebuildEpollLocked() {
// Allocate the new epoll instance and register the wake pipe.
mEpollFd = epoll_create(EPOLL_SIZE_HINT);//main
LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance: %s", strerror(errno));
struct epoll_event eventItem;
memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
eventItem.events = EPOLLIN;
eventItem.data.fd = mWakeEventFd;
int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeEventFd, & eventItem);//main
LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake event fd to epoll instance: %s",
strerror(errno));
for (size_t i = 0; i < mRequests.size(); i++) {
const Request& request = mRequests.valueAt(i);
struct epoll_event eventItem;
request.initEventItem(&eventItem);
int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, request.fd, & eventItem);
if (epollResult < 0) {
ALOGE("Error adding epoll events for fd %d while rebuilding epoll set: %s",
request.fd, strerror(errno));
}
}
}
eventfd 是 Linux 系统中一个用来通知事件的文件描述符,基于内核向用户空间应用发送通知的机制,可以有效地被用来实现用户空间事件驱动的应用程序。
简而言之:eventfd 就是用来触发事件通知,它只有一个系统调用接口:
int eventfd(unsigned int initval, int flags);
表示打开一个 eventfd 文件并返回文件描述符,支持 epoll/poll/select 操作。
在 Android 6.0 后,Handler 底层替换为 eventfd/epoll 实现。而 6.0 之前是由 pipe/epoll 实现的
int Looper::addFd(int fd, int ident, int events, Looper_callbackFunc callback, void* data) {
// use SimpleLooperCallback as adapter from handleEvent to callback function
return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : NULL, data);
}
int Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data) {
if (!callback.get()) {
if (! mAllowNonCallbacks) {
ALOGE("Invalid attempt to set NULL callback but not allowed for this looper.");
return -1;
}
if (ident < 0) {
ALOGE("Invalid attempt to set NULL callback with ident < 0.");
return -1;
}
} else {
ident = POLL_CALLBACK;
}
Request request;
request.fd = fd;
request.ident = ident;
request.events = events;
request.seq = mNextRequestSeq++;
request.callback = callback;
request.data = data;
struct epoll_event eventItem;
request.initEventItem(&eventItem);
ssize_t requestIndex = mRequests.indexOfKey(fd);
if (requestIndex < 0) {
int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem);
mRequests.add(fd, request);
} else {
int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem);
}
}
void Looper::Request::initEventItem(struct epoll_event* eventItem) const {
int epollEvents = 0;
if (events & EVENT_INPUT) epollEvents |= EPOLLIN;
if (events & EVENT_OUTPUT) epollEvents |= EPOLLOUT;
memset(eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
eventItem->events = epollEvents;
eventItem->data.fd = fd;
}
//timeoutMillis由MessageQueue的next()方法中计算并提供,队列中有message时,时间为msg.when-now,否则无消息,为-1表示一直在epoll中等待消息
int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
int result = 0;
for (;;) {
while (mResponseIndex < mResponses.size()) {
const Response& response = mResponses.itemAt(mResponseIndex++);
int ident = response.request.ident;
if (ident >= 0) {
int fd = response.request.fd;
int events = response.events;
void* data = response.request.data;
if (outFd != NULL) *outFd = fd;
if (outEvents != NULL) *outEvents = events;
if (outData != NULL) *outData = data;
return ident;
}
}
if (result != 0) {
if (outFd != NULL) *outFd = 0;
if (outEvents != NULL) *outEvents = 0;
if (outData != NULL) *outData = NULL;
return result;
}
result = pollInner(timeoutMillis);
}
}
// Maximum number of file descriptors for which to retrieve poll events each iteration.
static const int EPOLL_MAX_EVENTS = 16;
int Looper::pollInner(int timeoutMillis) {
// Poll.
int result = POLL_WAKE;
mResponses.clear();
mResponseIndex = 0;
struct epoll_event eventItems[EPOLL_MAX_EVENTS];
int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
for (int i = 0; i < eventCount; i++) {
int fd = eventItems[i].data.fd;
uint32_t epollEvents = eventItems[i].events;
if (fd == mWakeEventFd) {
if (epollEvents & EPOLLIN) {
awoken();
}
} else {
ssize_t requestIndex = mRequests.indexOfKey(fd);
if (requestIndex >= 0) {
int events = 0;
if (epollEvents & EPOLLIN) events |= EVENT_INPUT;
if (epollEvents & EPOLLOUT) events |= EVENT_OUTPUT;
if (epollEvents & EPOLLERR) events |= EVENT_ERROR;
if (epollEvents & EPOLLHUP) events |= EVENT_HANGUP;
pushResponse(events, mRequests.valueAt(requestIndex));
}
}
}
//1:处理C层发送的消息
// Invoke pending message callbacks.
mNextMessageUptime = LLONG_MAX;
while (mMessageEnvelopes.size() != 0) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);
if (messageEnvelope.uptime <= now) {
// Remove the envelope from the list.
// We keep a strong reference to the handler until the call to handleMessage
// finishes. Then we drop it so that the handler can be deleted *before*
// we reacquire our lock.
{ // obtain handler
sp<MessageHandler> handler = messageEnvelope.handler;
Message message = messageEnvelope.message;
mMessageEnvelopes.removeAt(0);
mSendingMessage = true;
mLock.unlock();
handler->handleMessage(message);
} // release handler
mLock.lock();
mSendingMessage = false;
result = POLL_CALLBACK;
} else {
// The last message left at the head of the queue determines the next wakeup time.
mNextMessageUptime = messageEnvelope.uptime;
break;
}
}
//2:回调通过addFd添加进来的监听
// Invoke all response callbacks.
for (size_t i = 0; i < mResponses.size(); i++) {
Response& response = mResponses.editItemAt(i);
if (response.request.ident == POLL_CALLBACK) {
int fd = response.request.fd;
int events = response.events;
void* data = response.request.data;
// Invoke the callback. Note that the file descriptor may be closed by
// the callback (and potentially even reused) before the function returns so
// we need to be a little careful when removing the file descriptor afterwards.
int callbackResult = response.request.callback->handleEvent(fd, events, data);//回调flutter在MessageLoopAndroid构造方法中设置的callback监听
if (callbackResult == 0) {//callback方法返回0时表示需要移除该fd监听
removeFd(fd, response.request.seq);
}
// Clear the callback reference in the response structure promptly because we
// will not clear the response vector itself until the next poll.
response.request.callback.clear();
result = POLL_CALLBACK;
}
}
return result;//3::返回之后回到java层的死循环处处理java层消息
}
void Looper::pushResponse(int events, const Request& request) {
Response response;
response.events = events;
response.request = request;
mResponses.push(response);
}