da59a3cc30ef0f6ebb734a24d755515f636b4971
[ccan] / ccan / io / test / run-10-many.c
1 #include <ccan/io/io.h>
2 /* Include the C files directly. */
3 #include <ccan/io/poll.c>
4 #include <ccan/io/io.c>
5 #include <ccan/tap/tap.h>
6 #include <sys/wait.h>
7 #include <stdio.h>
8
9 #define NUM 100
10 #define NUM_ITERS 1000
11
12 struct buffer {
13         int iters;
14         struct io_conn *reader, *writer;
15         char buf[32];
16 };
17
18 static struct io_plan poke_reader(struct io_conn *conn, struct buffer *buf);
19
20 static struct io_plan poke_writer(struct io_conn *conn, struct buffer *buf)
21 {
22         assert(conn == buf->reader);
23
24         if (buf->iters == NUM_ITERS)
25                 return io_close();
26
27         /* You write. */
28         io_wake(buf->writer,
29                 io_write(&buf->buf, sizeof(buf->buf), poke_reader, buf));
30
31         /* I'll wait until you wake me. */
32         return io_idle();
33 }
34
35 static struct io_plan poke_reader(struct io_conn *conn, struct buffer *buf)
36 {
37         assert(conn == buf->writer);
38         /* You read. */
39         io_wake(buf->reader,
40                 io_read(&buf->buf, sizeof(buf->buf), poke_writer, buf));
41
42         if (++buf->iters == NUM_ITERS)
43                 return io_close();
44
45         /* I'll wait until you tell me to write. */
46         return io_idle();
47 }
48
49 static struct buffer buf[NUM];
50
51 int main(void)
52 {
53         unsigned int i;
54         int fds[2], last_read, last_write;
55
56         plan_tests(5 + NUM);
57
58         ok1(pipe(fds) == 0);
59         last_read = fds[0];
60         last_write = fds[1];
61
62         for (i = 1; i < NUM; i++) {
63                 if (pipe(fds) < 0)
64                         break;
65                 memset(buf[i].buf, i, sizeof(buf[i].buf));
66                 sprintf(buf[i].buf, "%i-%i", i, i);
67
68                 /* Wait for writer to tell us to read. */
69                 buf[i].reader = io_new_conn(last_read, io_idle());
70                 if (!buf[i].reader)
71                         break;
72                 buf[i].writer = io_new_conn(fds[1],
73                                             io_write(&buf[i].buf,
74                                                      sizeof(buf[i].buf),
75                                                      poke_reader, &buf[i]));
76                 if (!buf[i].writer)
77                         break;
78                 last_read = fds[0];
79         }
80         if (!ok1(i == NUM))
81                 exit(exit_status());
82
83         /* Last one completes the cirle. */
84         i = 0;
85         sprintf(buf[i].buf, "%i-%i", i, i);
86         buf[i].reader = io_new_conn(last_read, io_idle());
87         ok1(buf[i].reader);
88         buf[i].writer = io_new_conn(last_write,
89                                     io_write(&buf[i].buf, sizeof(buf[i].buf),
90                                              poke_reader, &buf[i]));
91         ok1(buf[i].writer);
92
93         /* They should eventually exit */
94         ok1(io_loop() == NULL);
95
96         for (i = 0; i < NUM; i++) {
97                 char b[sizeof(buf[0].buf)];
98                 memset(b, i, sizeof(b));
99                 sprintf(b, "%i-%i", i, i);
100                 ok1(memcmp(b, buf[(i + NUM_ITERS) % NUM].buf, sizeof(b)) == 0);
101         }
102
103         /* This exits depending on whether all tests passed */
104         return exit_status();
105 }