dfa: reorder enum for efficiency
[gnulib.git] / tests / test-nonblocking-writer.h
blob4abbdab2f6ae280f72cc1a5b8886387609b82edc
1 /* The writer part of a test program for non-blocking communication.
3 Copyright (C) 2011-2018 Free Software Foundation, Inc.
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
18 /* This program implements 4 tests:
20 test == 0:
21 Test blocking write() with blocking read().
23 Timeline Main process Child process
24 0 s Start Start, read(10000)
25 1 s write(20000) Return from read(10000)
26 2 s Next read(10000)
27 2 s Return from write(20000) Return from read(10000)
29 test == 1:
30 Test non-blocking write() with blocking read().
32 Timeline Main process Child process
33 0 s Start Start, read(10000)
34 1 s write(20000) Return from read(10000)
35 Return with at least 10000,
36 Repeatedly continue
37 write() of the rest
38 2 s Next read(10000)
39 2 s Return from write(10000) Return from read(10000)
41 test == 2:
42 Test blocking write() with non-blocking read().
44 Timeline Main process Child process
45 0 s Start Start, read(10000)
46 repeatedly polling
47 1 s write(20000) Return from read(10000)
48 2 s Next read(10000)
49 2 s Return from write(20000) Return from read(10000)
51 test == 3:
52 Test non-blocking write() with non-blocking read().
55 #include "test-nonblocking-misc.h"
57 /* Execute the writer loop.
58 Returns 0 if successful, 1 if data_block_size is too small. */
59 static int
60 main_writer_loop (int test, size_t data_block_size, int fd,
61 bool has_large_buffer)
63 int too_small = 0;
64 unsigned char *data;
66 /* Set up the data to transfer. */
67 data = init_data (data_block_size);
69 switch (test)
71 TIMING_DECLS
72 ssize_t ret;
74 case 0: /* Test blocking write() with blocking read(). */
75 case 2: /* Test blocking write() with non-blocking read(). */
77 int saved_errno;
79 usleep (1000000);
81 dbgfprintf (stderr, "%s:1: >> write (%lu)\n", PROG_ROLE,
82 (unsigned long) 2 * data_block_size);
83 START_TIMING
84 ret = write (fd, data, 2 * data_block_size);
85 saved_errno = errno;
86 END_TIMING
87 dbgfprintf (stderr, "%s:1: << write -> %ld%s\n", PROG_ROLE,
88 (long) ret, dbgstrerror (ret < 0, saved_errno));
89 ASSERT (ret == 2 * data_block_size);
90 if (!has_large_buffer)
92 /* This assertion fails if data_block_size is too small. */
93 if (!(spent_time > 0.5))
95 fprintf (stderr,
96 "%s:1: spent_time = %g, data_block_size too small\n",
97 PROG_ROLE, spent_time);
98 too_small = 1;
101 ASSERT (spent_time < 1.5);
103 break;
105 case 1: /* Test non-blocking write() with blocking read(). */
106 case 3: /* Test non-blocking write() with non-blocking read(). */
108 size_t bytes_written;
109 int saved_errno;
111 usleep (1000000);
113 bytes_written = 0;
114 while (bytes_written < 2 * data_block_size)
116 dbgfprintf (stderr, "%s:2: >> write (%lu)\n", PROG_ROLE,
117 (unsigned long) (2 * data_block_size - bytes_written));
118 START_TIMING
119 ret = write (fd, data + bytes_written,
120 2 * data_block_size - bytes_written);
121 saved_errno = errno;
122 END_TIMING
123 dbgfprintf (stderr, "%s:2: << write -> %ld%s\n", PROG_ROLE,
124 (long) ret, dbgstrerror (ret < 0, saved_errno));
125 if (ret < 0 && bytes_written >= data_block_size)
127 ASSERT (saved_errno == EAGAIN || saved_errno == EWOULDBLOCK);
128 ASSERT (spent_time < 0.5);
129 break;
131 /* This assertion fails if the non-blocking flag is effectively not
132 set on fd. */
133 ASSERT (spent_time < 0.5);
134 if (ret < 0)
136 ASSERT (saved_errno == EAGAIN || saved_errno == EWOULDBLOCK);
137 usleep (SMALL_DELAY);
139 else
141 /* This assertion fails if data_block_size is too small. */
142 if (!(ret > 0))
144 fprintf (stderr,
145 "%s:1: spent_time = %g, data_block_size too small\n",
146 PROG_ROLE, spent_time);
147 too_small = 1;
149 bytes_written += ret;
152 ASSERT (bytes_written >= data_block_size);
154 while (bytes_written < 2 * data_block_size)
156 dbgfprintf (stderr, "%s:3: >> write (%lu)\n", PROG_ROLE,
157 (unsigned long) (2 * data_block_size - bytes_written));
158 START_TIMING
159 ret = write (fd, data + bytes_written,
160 2 * data_block_size - bytes_written);
161 saved_errno = errno;
162 END_TIMING
163 dbgfprintf (stderr, "%s:3: << write -> %ld%s\n", PROG_ROLE,
164 (long) ret, dbgstrerror (ret < 0, saved_errno));
165 ASSERT (spent_time < 0.5);
166 if (ret < 0)
168 ASSERT (saved_errno == EAGAIN || saved_errno == EWOULDBLOCK);
169 usleep (SMALL_DELAY);
171 else
173 ASSERT (ret > 0);
174 bytes_written += ret;
178 break;
180 default:
181 abort ();
184 free (data);
185 return too_small;