io: fix nasty io_wake corner case.
[ccan] / ccan / io / test / run-40-wakeup-mutual.c
1 /* Test previous issue: in duplex case, we wake reader reader wakes writer. */
2 #include <ccan/io/io.h>
3 /* Include the C files directly. */
4 #include <ccan/io/poll.c>
5 #include <ccan/io/io.c>
6 #include <ccan/tap/tap.h>
7 #include <sys/wait.h>
8 #include <stdio.h>
9
10 static struct io_plan *block_reading(struct io_conn *conn, void *unused)
11 {
12         static char buf[1];
13         return io_read(conn, buf, sizeof(buf), io_never, NULL);
14 }
15
16 static struct io_plan *writer_woken(struct io_conn *conn, void *unused)
17 {
18         pass("Writer woken up");
19         return io_write(conn, "1", 1, io_close_cb, NULL);
20 }
21
22 static struct io_plan *reader_woken(struct io_conn *conn, void *unused)
23 {
24         pass("Reader woken up");
25         /* Wake writer */
26         io_wake(conn);
27         return block_reading(conn, unused);
28 }
29
30 static struct io_plan *setup_conn(struct io_conn *conn, void *trigger)
31 {
32         return io_duplex(conn,
33                          io_wait(conn, trigger, reader_woken, NULL),
34                          io_out_wait(conn, conn, writer_woken, NULL));
35 }
36
37 int main(void)
38 {
39         int fds[2];
40         
41         plan_tests(3);
42         ok1(socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) == 0);
43
44         /* We use 'fds' as pointer to wake writer. */
45         io_new_conn(NULL, fds[0], setup_conn, fds);
46
47         io_wake(fds);
48         io_loop(NULL, NULL);
49
50         close(fds[1]);
51
52         /* This exits depending on whether all tests passed */
53         return exit_status();
54 }