diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2021-02-08 11:10:36 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-08 11:10:36 +0100 |
commit | 07ffdcf91595ed719386188fceb29791a43e6a02 (patch) | |
tree | 30b259d58e972ac5f08973b8af4e81f14cc0497d /src/libsystemd | |
parent | Use correct config parser for MountAPIVFS (#18501) (diff) | |
parent | sd-event: retrieve more events when epoll_wait() returns number equivalent to... (diff) | |
download | systemd-07ffdcf91595ed719386188fceb29791a43e6a02.tar.xz systemd-07ffdcf91595ed719386188fceb29791a43e6a02.zip |
Merge pull request #18331 from yuwata/test-udev-event-spawn
udev: add tests for udev_event_spawn()
Diffstat (limited to 'src/libsystemd')
-rw-r--r-- | src/libsystemd/sd-event/sd-event.c | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c index 05e21968ac..8abbefcf27 100644 --- a/src/libsystemd/sd-event/sd-event.c +++ b/src/libsystemd/sd-event/sd-event.c @@ -3781,8 +3781,8 @@ pending: } _public_ int sd_event_wait(sd_event *e, uint64_t timeout) { - size_t event_queue_max; - int r, m, i; + size_t n_event_queue, m; + int r, msec; assert_return(e, -EINVAL); assert_return(e = event_resolve(e), -ENOPKG); @@ -3795,29 +3795,45 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) { return 1; } - event_queue_max = MAX(e->n_sources, 1u); - if (!GREEDY_REALLOC(e->event_queue, e->event_queue_allocated, event_queue_max)) + n_event_queue = MAX(e->n_sources, 1u); + if (!GREEDY_REALLOC(e->event_queue, e->event_queue_allocated, n_event_queue)) return -ENOMEM; /* If we still have inotify data buffered, then query the other fds, but don't wait on it */ if (e->inotify_data_buffered) - timeout = 0; + msec = 0; + else + msec = timeout == (uint64_t) -1 ? -1 : (int) DIV_ROUND_UP(timeout, USEC_PER_MSEC); - m = epoll_wait(e->epoll_fd, e->event_queue, event_queue_max, - timeout == (uint64_t) -1 ? -1 : (int) DIV_ROUND_UP(timeout, USEC_PER_MSEC)); - if (m < 0) { - if (errno == EINTR) { - e->state = SD_EVENT_PENDING; - return 1; + for (;;) { + r = epoll_wait(e->epoll_fd, e->event_queue, e->event_queue_allocated, msec); + if (r < 0) { + if (errno == EINTR) { + e->state = SD_EVENT_PENDING; + return 1; + } + + r = -errno; + goto finish; } - r = -errno; - goto finish; + m = (size_t) r; + + if (m < e->event_queue_allocated) + break; + + if (e->event_queue_allocated >= n_event_queue * 10) + break; + + if (!GREEDY_REALLOC(e->event_queue, e->event_queue_allocated, e->event_queue_allocated + n_event_queue)) + return -ENOMEM; + + msec = 0; } triple_timestamp_get(&e->timestamp); - for (i = 0; i < m; i++) { + for (size_t i = 0; i < m; i++) { if (e->event_queue[i].data.ptr == INT_TO_PTR(SOURCE_WATCHDOG)) r = flush_timer(e, e->watchdog_fd, e->event_queue[i].events, NULL); |