diff mbox

[6/6] add test for aio poll and io_pgetevents

Message ID 20180104080325.14716-7-hch@lst.de (mailing list archive)
State New, archived
Headers show

Commit Message

Christoph Hellwig Jan. 4, 2018, 8:03 a.m. UTC
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 harness/cases/22.t | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 149 insertions(+)
 create mode 100644 harness/cases/22.t

Comments

Philippe Ombredanne Jan. 4, 2018, 10:24 a.m. UTC | #1
Dear Christoph,

On Thu, Jan 4, 2018 at 9:03 AM, Christoph Hellwig <hch@lst.de> wrote:
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  harness/cases/22.t | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 149 insertions(+)
>  create mode 100644 harness/cases/22.t
>
> diff --git a/harness/cases/22.t b/harness/cases/22.t
> new file mode 100644
> index 0000000..a9fec6b
> --- /dev/null
> +++ b/harness/cases/22.t
> @@ -0,0 +1,149 @@
> +/*
> + * Copyright (C) 2006-2018 Free Software Foundation, Inc.
> + * Copyright (C) 2018 Christoph Hellwig.
> + * License: LGPLv2.1 or later.

Would you consider using an SPDX tag instead as documented in Thomas
doc patches [1]? This rather close to what you use today and would
come out as this, on the first line:

SPDX-License-Identifier: LGPL-2.1+

Thank you!

[1] https://lkml.org/lkml/2017/12/28/323
Christoph Hellwig Jan. 4, 2018, 10:29 a.m. UTC | #2
On Thu, Jan 04, 2018 at 11:24:16AM +0100, Philippe Ombredanne wrote:
> Would you consider using an SPDX tag instead as documented in Thomas
> doc patches [1]? This rather close to what you use today and would
> come out as this, on the first line:
> 
> SPDX-License-Identifier: LGPL-2.1+
> 
> Thank you!

Only if the libaio maintainers do the work of actually explaning what
such tags mean in their project, because without that it would be
entirely meaningless.
Jeff Moyer Jan. 5, 2018, 10:55 p.m. UTC | #3
Christoph Hellwig <hch@lst.de> writes:

> +	p = fork();
> +	switch (p) {
[snip]
> +	default:
> +		close(pipe1[0]);
> +		close(pipe2[1]);
> +
> +		io_prep_poll(&iocb, pipe2[0], POLLIN);
> +
> +		ret = io_setup(1, &ctx);
> +		if (ret) {
> +			printf("child: io_setup failed\n");

parent

> +			return 1;
> +		}
> +
> +		ret = io_submit(ctx, 1, iocbs);
> +		if (ret != 1) {
> +			printf("child: io_submit failed\n");

parent

Other than that, looks ok to me.  Thanks for writing a test!
I can fix this up, no need to repost.

-Jeff
diff mbox

Patch

diff --git a/harness/cases/22.t b/harness/cases/22.t
new file mode 100644
index 0000000..a9fec6b
--- /dev/null
+++ b/harness/cases/22.t
@@ -0,0 +1,149 @@ 
+/*
+ * Copyright (C) 2006-2018 Free Software Foundation, Inc.
+ * Copyright (C) 2018 Christoph Hellwig.
+ * License: LGPLv2.1 or later.
+ *
+ * Description: test aio poll and io_pgetevents signal handling.
+ *
+ * Very roughly based on glibc tst-pselect.c.
+ */
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/poll.h>
+#include <sys/wait.h>
+#include <stdlib.h>
+
+static volatile int handler_called;
+
+static void
+handler(int sig)
+{
+	handler_called = 1;
+}
+
+int test_main(void)
+{
+	struct timespec to = { .tv_sec = 0, .tv_nsec = 500000000 };
+	pid_t parent = getpid(), p;
+	int pipe1[2], pipe2[2];
+	struct sigaction sa = { .sa_flags = 0 };
+	sigset_t sigmask;
+	struct io_context *ctx = NULL;
+	struct io_event ev;
+	struct iocb iocb;
+	struct iocb *iocbs[] = { &iocb };
+	int ret;
+
+	sigemptyset(&sa.sa_mask);
+
+	sa.sa_handler = handler;
+	if (sigaction(SIGUSR1, &sa, NULL) != 0) {
+		printf("sigaction(1) failed\n");
+		return 1;
+	}
+
+	sa.sa_handler = SIG_IGN;
+	if (sigaction(SIGCHLD, &sa, NULL) != 0) {
+		printf("sigaction(2) failed\n");
+		return 1;
+	}
+
+	sigemptyset(&sigmask);
+	sigaddset(&sigmask, SIGUSR1);
+	if (sigprocmask(SIG_BLOCK, &sigmask, NULL) != 0) {
+		printf("sigprocmask failed\n");
+		return 1;
+	}
+
+	if (pipe(pipe1) != 0 || pipe(pipe2) != 0) {
+		printf("pipe failed\n");
+		return 1;
+	}
+
+	sigprocmask(SIG_SETMASK, NULL, &sigmask);
+	sigdelset(&sigmask, SIGUSR1);
+
+	p = fork();
+	switch (p) {
+	case -1:
+		printf("fork failed\n");
+		exit(2);
+	case 0:
+		close(pipe1[1]);
+		close(pipe2[0]);
+
+		ret = io_setup(1, &ctx);
+		if (ret) {
+			printf("child: io_setup failed\n");
+			return 1;
+		}
+
+		io_prep_poll(&iocb, pipe1[0], POLLIN);
+		ret = io_submit(ctx, 1, iocbs);
+		if (ret != 1) {
+			printf("child: io_submit failed\n");
+			return 1;
+		}
+
+		do {
+			if (getppid() != parent) {
+				printf("parent died\n");
+				exit(2);
+			}
+			ret = io_pgetevents(ctx, 1, 1, &ev, &to, &sigmask);
+		} while (ret == 0);
+
+		if (ret != -EINTR) {
+			printf("child: io_pgetevents did not set errno to EINTR\n");
+			return 1;
+		}
+
+		do {
+			errno = 0;
+			ret = write(pipe2[1], "foo", 3);
+		} while (ret == -1 && errno == EINTR);
+
+		exit(0);
+	default:
+		close(pipe1[0]);
+		close(pipe2[1]);
+
+		io_prep_poll(&iocb, pipe2[0], POLLIN);
+
+		ret = io_setup(1, &ctx);
+		if (ret) {
+			printf("child: io_setup failed\n");
+			return 1;
+		}
+
+		ret = io_submit(ctx, 1, iocbs);
+		if (ret != 1) {
+			printf("child: io_submit failed\n");
+			return 1;
+		}
+
+		kill(p, SIGUSR1);
+
+		ret = io_pgetevents(ctx, 1, 1, &ev, NULL, &sigmask);
+		if (ret < 0) {
+			printf("parent: io_pgetevents failed\n");
+			return 1;
+		}
+		if (ret != 1) {
+			printf("parent: io_pgetevents did not report event\n");
+			return 1;
+		}
+		if (ev.obj != &iocb) {
+			printf("parent: io_pgetevents reports wrong fd\n");
+			return 1;
+		}
+		if (ev.res != POLLIN) {
+			printf("parent: io_pgetevents did not report readable fd\n");
+			return 1;
+		}
+
+		return 0;
+	}
+}