100
void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
101
struct uv__epoll_event* events;
105
assert(loop->watchers != NULL);
107
events = (struct uv__epoll_event*) loop->watchers[loop->nwatchers];
108
nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
112
/* Invalidate events with same file descriptor */
113
for (i = 0; i < nfds; i++)
114
if ((int) events[i].data == fd)
100
119
void uv__io_poll(uv_loop_t* loop, int timeout) {
101
120
struct uv__epoll_event events[1024];
102
121
struct uv__epoll_event* pe;
211
assert(loop->watchers != NULL);
212
loop->watchers[loop->nwatchers] = (void*) events;
213
loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
192
214
for (i = 0; i < nfds; i++) {
218
/* Skip invalidated events, see uv__platform_invalidate_fd */
197
223
assert((unsigned) fd < loop->nwatchers);
211
w->cb(loop, w, pe->events);
237
/* Give users only events they're interested in. Prevents spurious
238
* callbacks when previous callback invocation in this loop has stopped
239
* the current watcher. Also, filters out events that users has not
240
* requested us to watch.
242
pe->events &= w->pevents | UV__POLLERR | UV__POLLHUP;
244
/* Work around an epoll quirk where it sometimes reports just the
245
* EPOLLERR or EPOLLHUP event. In order to force the event loop to
246
* move forward, we merge in the read/write events that the watcher
247
* is interested in; uv__read() and uv__write() will then deal with
248
* the error or hangup in the usual fashion.
250
* Note to self: happens when epoll reports EPOLLIN|EPOLLHUP, the user
251
* reads the available data, calls uv_read_stop(), then sometime later
252
* calls uv_read_start() again. By then, libuv has forgotten about the
253
* hangup and the kernel won't report EPOLLIN again because there's
254
* nothing left to read. If anything, libuv is to blame here. The
255
* current hack is just a quick bandaid; to properly fix it, libuv
256
* needs to remember the error/hangup event. We should get that for
257
* free when we switch over to edge-triggered I/O.
259
if (pe->events == UV__EPOLLERR || pe->events == UV__EPOLLHUP)
260
pe->events |= w->pevents & (UV__EPOLLIN | UV__EPOLLOUT);
262
if (pe->events != 0) {
263
w->cb(loop, w, pe->events);
267
loop->watchers[loop->nwatchers] = NULL;
268
loop->watchers[loop->nwatchers + 1] = NULL;
215
270
if (nevents != 0) {
216
271
if (nfds == ARRAY_SIZE(events) && --count != 0) {