* Event loop shared between the parent, and the connections. Could be * split in two, as they don't handle the same types of events. For the per * connection loop, 'c' is valid. For the main loop, it's NULL. */
| 2016 | * connection loop, 'c' is valid. For the main loop, it's NULL. |
| 2017 | */ |
| 2018 | static int __event_loop(struct io_uring *ring, struct conn *c) |
| 2019 | { |
| 2020 | struct __kernel_timespec active_ts, idle_ts; |
| 2021 | int flags; |
| 2022 | |
| 2023 | idle_ts.tv_sec = 0; |
| 2024 | idle_ts.tv_nsec = 100000000LL; |
| 2025 | active_ts = idle_ts; |
| 2026 | if (wait_usec > 1000000) { |
| 2027 | active_ts.tv_sec = wait_usec / 1000000; |
| 2028 | wait_usec -= active_ts.tv_sec * 1000000; |
| 2029 | } |
| 2030 | active_ts.tv_nsec = wait_usec * 1000; |
| 2031 | |
| 2032 | gettimeofday(&last_housekeeping, NULL); |
| 2033 | |
| 2034 | flags = 0; |
| 2035 | while (1) { |
| 2036 | struct __kernel_timespec *ts = &idle_ts; |
| 2037 | struct io_uring_cqe *cqe; |
| 2038 | unsigned int head; |
| 2039 | int ret, i, to_wait; |
| 2040 | |
| 2041 | /* |
| 2042 | * If wait_batch is set higher than 1, then we'll wait on |
| 2043 | * that amount of CQEs to be posted each loop. If used with |
| 2044 | * DEFER_TASKRUN, this can provide a substantial reduction |
| 2045 | * in context switch rate as the task isn't woken until the |
| 2046 | * requested number of events can be returned. |
| 2047 | * |
| 2048 | * Can be used with -t to set a wait_usec timeout as well. |
| 2049 | * For example, if an application can deal with 250 usec |
| 2050 | * of wait latencies, it can set -w8 -t250 which will cause |
| 2051 | * io_uring to return when either 8 events have been received, |
| 2052 | * or if 250 usec of waiting has passed. |
| 2053 | * |
| 2054 | * If we don't have any open connections, wait on just 1 |
| 2055 | * always. |
| 2056 | */ |
| 2057 | to_wait = 1; |
| 2058 | if (open_conns && !flags) { |
| 2059 | ts = &active_ts; |
| 2060 | to_wait = wait_batch; |
| 2061 | } |
| 2062 | |
| 2063 | vlog("Submit and wait for %d\n", to_wait); |
| 2064 | ret = io_uring_submit_and_wait_timeout(ring, &cqe, to_wait, ts, NULL); |
| 2065 | |
| 2066 | if (*ring->cq.koverflow) |
| 2067 | printf("overflow %u\n", *ring->cq.koverflow); |
| 2068 | if (*ring->sq.kflags & IORING_SQ_CQ_OVERFLOW) |
| 2069 | printf("saw overflow\n"); |
| 2070 | |
| 2071 | vlog("Submit and wait: %d\n", ret); |
| 2072 | |
| 2073 | i = flags = 0; |
| 2074 | io_uring_for_each_cqe(ring, head, cqe) { |
| 2075 | if (handle_cqe(ring, cqe)) |
no test coverage detected