unix: short-circuit on no-op io watcher changes

Don't add the io watcher to the watcher queue if the requested change
is effectively a no-op, that is, when the event mask doesn't change.

The exception here is sunos because the event ports backend requires
that watched file descriptors are re-added on every turn of the event
loop.

This commit is a micro-optimization, it does not change the event
loop's observable behavior in any way.
This commit is contained in:
Ben Noordhuis 2013-02-22 17:02:04 +01:00
parent da0b84d4e8
commit c98083ef26
3 changed files with 14 additions and 20 deletions

View File

@ -603,14 +603,6 @@ void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd) {
}
/* Note that uv__io_start() and uv__io_stop() can't simply remove the watcher
* from the queue when the new event mask equals the old one. The event ports
* backend operates exclusively in single-shot mode and needs to rearm all fds
* before each call to port_getn(). It's up to the individual backends to
* filter out superfluous event mask modifications.
*/
void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT)));
assert(0 != events);
@ -620,6 +612,20 @@ void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
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) {
if (w->events == 0 && !ngx_queue_empty(&w->watcher_queue)) {
ngx_queue_remove(&w->watcher_queue);
ngx_queue_init(&w->watcher_queue);
}
return;
}
#endif
if (ngx_queue_empty(&w->watcher_queue))
ngx_queue_insert_tail(&loop->watcher_queue, &w->watcher_queue);

View File

@ -84,12 +84,6 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
assert(w->fd >= 0);
assert(w->fd < (int) loop->nwatchers);
/* Filter out no-op changes. This is for compatibility with the event ports
* backend, see uv__io_start().
*/
if (w->events == w->pevents)
continue;
if ((w->events & UV__POLLIN) == 0 && (w->pevents & UV__POLLIN) != 0) {
filter = EVFILT_READ;
fflags = 0;

View File

@ -140,12 +140,6 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
assert(w->fd >= 0);
assert(w->fd < (int) loop->nwatchers);
/* Filter out no-op changes. This is for compatibility with the event ports
* backend, see the comment in uv__io_start().
*/
if (w->events == w->pevents)
continue;
e.events = w->pevents;
e.data = w->fd;