| 1587 | |
| 1588 | |
| 1589 | static int test_timeout_multishot_nr(struct io_uring *ring) |
| 1590 | { |
| 1591 | struct io_uring_cqe *cqe; |
| 1592 | struct io_uring_sqe *sqe; |
| 1593 | struct __kernel_timespec ts; |
| 1594 | int ret; |
| 1595 | |
| 1596 | if (no_multishot) |
| 1597 | return T_EXIT_SKIP; |
| 1598 | |
| 1599 | sqe = io_uring_get_sqe(ring); |
| 1600 | if (!sqe) { |
| 1601 | fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__); |
| 1602 | goto err; |
| 1603 | } |
| 1604 | |
| 1605 | msec_to_ts(&ts, TIMEOUT_MSEC); |
| 1606 | io_uring_prep_timeout(sqe, &ts, 3, IORING_TIMEOUT_MULTISHOT); |
| 1607 | io_uring_sqe_set_data(sqe, (void *) 1); |
| 1608 | |
| 1609 | ret = io_uring_submit(ring); |
| 1610 | if (ret <= 0) { |
| 1611 | fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret); |
| 1612 | goto err; |
| 1613 | } |
| 1614 | |
| 1615 | for (int i = 0; i < 3; i++) { |
| 1616 | ret = io_uring_wait_cqe(ring, &cqe); |
| 1617 | if (ret < 0) { |
| 1618 | fprintf(stderr, "%s: wait completion %d\n", __FUNCTION__, ret); |
| 1619 | goto err; |
| 1620 | } |
| 1621 | |
| 1622 | if (i < 2 && !(cqe->flags & IORING_CQE_F_MORE)) { |
| 1623 | fprintf(stderr, "%s: flag not set in cqe\n", __FUNCTION__); |
| 1624 | goto err; |
| 1625 | } |
| 1626 | if (i == 3 && (cqe->flags & IORING_CQE_F_MORE)) { |
| 1627 | fprintf(stderr, "%s: flag set in cqe\n", __FUNCTION__); |
| 1628 | goto err; |
| 1629 | } |
| 1630 | |
| 1631 | ret = cqe->res; |
| 1632 | if (ret != -ETIME) { |
| 1633 | fprintf(stderr, "%s: Timeout: %s\n", __FUNCTION__, strerror(-ret)); |
| 1634 | goto err; |
| 1635 | } |
| 1636 | |
| 1637 | io_uring_cqe_seen(ring, cqe); |
| 1638 | } |
| 1639 | |
| 1640 | msec_to_ts(&ts, 2 * TIMEOUT_MSEC); |
| 1641 | ret = io_uring_wait_cqe_timeout(ring, &cqe, &ts); |
| 1642 | if (ret != -ETIME) { |
| 1643 | fprintf(stderr, "%s: wait completion timeout %s\n", __FUNCTION__, strerror(-ret)); |
| 1644 | goto err; |
| 1645 | } |
| 1646 |
no test coverage detected