mirror of
https://github.com/openharmony/third_party_liburing.git
synced 2026-08-27 02:51:16 -04:00
0ae77b95ef
Signed-off-by: fangzhiyi18 <fangzhiyi1@huawei.com>
106 lines
1.9 KiB
C
106 lines
1.9 KiB
C
/* SPDX-License-Identifier: MIT */
|
|
/*
|
|
* Description: check that multiple receives on the same socket don't get
|
|
* stalled if multiple wakers race with the socket readiness.
|
|
*/
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <pthread.h>
|
|
#include <sys/socket.h>
|
|
|
|
#include "liburing.h"
|
|
#include "helpers.h"
|
|
|
|
#define NREQS 64
|
|
|
|
struct data {
|
|
pthread_barrier_t barrier;
|
|
int fd;
|
|
};
|
|
|
|
static void *thread(void *data)
|
|
{
|
|
struct data *d = data;
|
|
char buf[64];
|
|
int ret, i;
|
|
|
|
pthread_barrier_wait(&d->barrier);
|
|
for (i = 0; i < NREQS; i++) {
|
|
ret = write(d->fd, buf, sizeof(buf));
|
|
if (ret != 64)
|
|
fprintf(stderr, "wrote short %d\n", ret);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static int test(struct io_uring *ring, struct data *d)
|
|
{
|
|
struct io_uring_sqe *sqe;
|
|
struct io_uring_cqe *cqe;
|
|
int fd[2], ret, i;
|
|
char buf[64];
|
|
pthread_t t;
|
|
void *ret2;
|
|
|
|
if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fd) < 0) {
|
|
perror("socketpair");
|
|
return T_EXIT_FAIL;
|
|
}
|
|
|
|
d->fd = fd[1];
|
|
|
|
pthread_create(&t, NULL, thread, d);
|
|
|
|
for (i = 0; i < NREQS; i++) {
|
|
sqe = io_uring_get_sqe(ring);
|
|
io_uring_prep_recv(sqe, fd[0], buf, sizeof(buf), 0);
|
|
}
|
|
|
|
pthread_barrier_wait(&d->barrier);
|
|
|
|
ret = io_uring_submit(ring);
|
|
if (ret != NREQS) {
|
|
fprintf(stderr, "submit %d\n", ret);
|
|
return T_EXIT_FAIL;
|
|
}
|
|
|
|
for (i = 0; i < NREQS; i++) {
|
|
ret = io_uring_wait_cqe(ring, &cqe);
|
|
if (ret) {
|
|
fprintf(stderr, "cqe wait %d\n", ret);
|
|
return T_EXIT_FAIL;
|
|
}
|
|
io_uring_cqe_seen(ring, cqe);
|
|
}
|
|
|
|
close(fd[0]);
|
|
close(fd[1]);
|
|
pthread_join(t, &ret2);
|
|
return T_EXIT_PASS;
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
struct io_uring ring;
|
|
struct data d;
|
|
int i, ret;
|
|
|
|
if (argc > 1)
|
|
return T_EXIT_SKIP;
|
|
|
|
pthread_barrier_init(&d.barrier, NULL, 2);
|
|
|
|
io_uring_queue_init(NREQS, &ring, 0);
|
|
|
|
for (i = 0; i < 1000; i++) {
|
|
ret = test(&ring, &d);
|
|
if (ret != T_EXIT_PASS) {
|
|
fprintf(stderr, "Test failed\n");
|
|
return T_EXIT_FAIL;
|
|
}
|
|
}
|
|
|
|
return T_EXIT_PASS;
|
|
}
|