void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI)));
assert(0 != events);
assert(w->fd >= 0);
assert(w->fd < INT_MAX);
w->pevents |= events;
maybe_resize(loop, w->fd + 1);
#if !defined(__sun)
/* The event ports backend needs to rearm all file descriptors on each and
* every tick of the event loop but the other backends allow us to
* short-circuit here if the event mask is unchanged.
*/
if (w->events == w->pevents)
return;
#endif
if (QUEUE_EMPTY(&w->watcher_queue))
QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue);
if (loop->watchers[w->fd] == NULL) {
loop->watchers[w->fd] = w;
loop->nfds++;
}
}
uv__io_start:从函数名即可看出,该函数用于启动io监测
tcp使用例子:uv__io_start(stream->loop, &stream->io_watcher, POLLIN);
w->pevents |= events;
pevents:表示即将发生的事件。此处即为即将发生POLLIN事件
maybe_resize(loop, w->fd + 1);
libuv用watchers来监视这些fd,watchers是一个数组,如果fd为10,则存储在watchers[9]中,因此当遇到更多的fd时,需要扩大watchers的容量
#if !defined(__sun)
/* The event ports backend needs to rearm all file descriptors on each and
* every tick of the event loop but the other backends allow us to
* short-circuit here if the event mask is unchanged.
*/
if (w->events == w->pevents)
return;
#endifif (QUEUE_EMPTY(&w->watcher_queue))
QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue);if (loop->watchers[w->fd] == NULL) {
loop->watchers[w->fd] = w;
loop->nfds++;
}
events表示发生的事件,如果等于pevents,则结束。
(io还没start时,pevents代表即将发生的时间,例如EPOLLIN,当io被从队列取出后,准备要加入epoll时,events赋值为pevents,代表现在发生的事情。)
否则,则保存到watchers,并且添加到watcher_queue中
在uv__io_poll中,取出队列中的fd,加入到epoll,在uv__io_poll中,执行w->events = w->pevents;
这样下次再调用到uv__io_start时,就不会再加到队列中去了