diff options
Diffstat (limited to 'tools/lib/api/fd/array.c')
| -rw-r--r-- | tools/lib/api/fd/array.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/tools/lib/api/fd/array.c b/tools/lib/api/fd/array.c index f0f195207fca..67b73481df27 100644 --- a/tools/lib/api/fd/array.c +++ b/tools/lib/api/fd/array.c @@ -31,7 +31,8 @@ int fdarray__grow(struct fdarray *fda, int nr) priv = realloc(fda->priv, psize); if (priv == NULL) { - free(entries); + /* this will be freed by fdarray__exit() */ + fda->entries = entries; return -ENOMEM; } @@ -50,7 +51,7 @@ struct fdarray *fdarray__new(int nr_alloc, int nr_autogrow) if (fda != NULL) { if (fdarray__grow(fda, nr_alloc)) { - free(fda); + fdarray__delete(fda); fda = NULL; } else { fda->nr_autogrow = nr_autogrow; @@ -115,6 +116,9 @@ int fdarray__filter(struct fdarray *fda, short revents, return 0; for (fd = 0; fd < fda->nr; ++fd) { + if (fda->priv[fd].flags & fdarray_flag__nonfilterable) + continue; + if (!fda->entries[fd].events) continue; @@ -122,12 +126,17 @@ int fdarray__filter(struct fdarray *fda, short revents, if (entry_destructor) entry_destructor(fda, fd, arg); + /* + * Set fd to -1 so poll() ignores this entry; otherwise + * POLLHUP/POLLERR are still reported for events=0 fds + * (POSIX: always checked), causing a poll storm. + */ + fda->entries[fd].fd = -1; fda->entries[fd].revents = fda->entries[fd].events = 0; continue; } - if (!(fda->priv[fd].flags & fdarray_flag__nonfilterable)) - ++nr; + ++nr; } return nr; |
