diff options
Diffstat (limited to 'gnulib/tests/test-nonblocking-reader.h')
m--------- | gnulib | 0 | ||||
-rw-r--r-- | gnulib/tests/test-nonblocking-reader.h | 200 |
2 files changed, 200 insertions, 0 deletions
diff --git a/gnulib b/gnulib deleted file mode 160000 -Subproject 443bc5ffcf7429e557f4a371b0661abe98ddbc1 diff --git a/gnulib/tests/test-nonblocking-reader.h b/gnulib/tests/test-nonblocking-reader.h new file mode 100644 index 0000000..220862f --- /dev/null +++ b/gnulib/tests/test-nonblocking-reader.h @@ -0,0 +1,200 @@ +/* The reader part of a test program for non-blocking communication. + + Copyright (C) 2011 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* This program implements 4 tests: + + test == 0: + Test blocking write() with blocking read(). + + Timeline Main process Child process + 0 s Start Start, read(10000) + 1 s write(20000) Return from read(10000) + 2 s Next read(10000) + 2 s Return from write(20000) Return from read(10000) + + test == 1: + Test non-blocking write() with blocking read(). + + Timeline Main process Child process + 0 s Start Start, read(10000) + 1 s write(20000) Return from read(10000) + Return with at least 10000, + Repeatedly continue + write() of the rest + 2 s Next read(10000) + 2 s Return from write(10000) Return from read(10000) + + test == 2: + Test blocking write() with non-blocking read(). + + Timeline Main process Child process + 0 s Start Start, read(10000) + repeatedly polling + 1 s write(20000) Return from read(10000) + 2 s Next read(10000) + 2 s Return from write(20000) Return from read(10000) + + test == 3: + Test non-blocking write() with non-blocking read(). + */ + +#include "test-nonblocking-misc.h" + +static ssize_t +full_read (size_t fd, void *buf, size_t count) +{ + size_t bytes_read; + + bytes_read = 0; + while (bytes_read < count) + { + TIMING_DECLS + ssize_t ret; + int saved_errno; + + dbgfprintf (stderr, "%s: >> read (%lu)\n", PROG_ROLE, + (unsigned long) (count - bytes_read)); + START_TIMING + ret = read (fd, (char *) buf + bytes_read, count - bytes_read); + saved_errno = errno; + END_TIMING + dbgfprintf (stderr, "%s: << read -> %ld%s\n", PROG_ROLE, + (long) ret, dbgstrerror (ret < 0, saved_errno)); + if (ret < 0) + return -1; + else + { + ASSERT (ret > 0); + bytes_read += ret; + } + } + return bytes_read; +} + +static ssize_t +full_read_from_nonblocking_fd (size_t fd, void *buf, size_t count) +{ + size_t bytes_read; + + bytes_read = 0; + while (bytes_read < count) + { + TIMING_DECLS + ssize_t ret; + int saved_errno; + + dbgfprintf (stderr, "%s: >> read (%lu)\n", PROG_ROLE, + (unsigned long) (count - bytes_read)); + START_TIMING + ret = read (fd, (char *) buf + bytes_read, count - bytes_read); + saved_errno = errno; + END_TIMING + dbgfprintf (stderr, "%s: << read -> %ld%s\n", PROG_ROLE, + (long) ret, dbgstrerror (ret < 0, saved_errno)); + /* This assertion fails if the non-blocking flag is effectively not set + on fd. */ + ASSERT (spent_time < 0.5); + if (ret < 0) + { + ASSERT (saved_errno == EAGAIN); + usleep (SMALL_DELAY); + } + else + { + ASSERT (ret > 0); + bytes_read += ret; + } + } + return bytes_read; +} + +/* Execute the reader loop. */ +static void +main_reader_loop (int test, size_t data_block_size, int fd) +{ + unsigned char *expected; + unsigned char *data; + + /* Set up the expected data. */ + expected = init_data (data_block_size); + + data = (unsigned char *) malloc (2 * data_block_size); + ASSERT (data != NULL); + + switch (test) + { + TIMING_DECLS + ssize_t ret; + + case 0: /* Test blocking write() with blocking read(). */ + case 1: /* Test non-blocking write() with blocking read(). */ + START_TIMING + ret = full_read (fd, data, data_block_size); + END_TIMING + ASSERT (ret == data_block_size); + ASSERT (memcmp (data, expected, data_block_size) == 0); + ASSERT (spent_time > 0.5); + /* This assertion fails if data_block_size is very large and + ENABLE_DEBUGGING is 1. */ + ASSERT (spent_time < 1.5); + + usleep (1000000); + + START_TIMING + ret = full_read (fd, data, data_block_size); + END_TIMING + ASSERT (ret == data_block_size); + ASSERT (memcmp (data, expected + data_block_size, data_block_size) == 0); + /* This assertion fails if data_block_size is much larger than needed + and SMALL_DELAY is too large. */ + ASSERT (spent_time < 0.5); + + break; + + case 2: /* Test blocking write() with non-blocking read(). */ + case 3: /* Test non-blocking write() with non-blocking read(). */ + START_TIMING + ret = full_read_from_nonblocking_fd (fd, data, data_block_size); + END_TIMING + ASSERT (ret == data_block_size); + ASSERT (memcmp (data, expected, data_block_size) == 0); + ASSERT (spent_time > 0.5); + /* This assertion fails if data_block_size is much larger than needed + and SMALL_DELAY is too large, or if data_block_size is very large and + ENABLE_DEBUGGING is 1. */ + ASSERT (spent_time < 1.5); + + usleep (1000000); + + START_TIMING + ret = full_read_from_nonblocking_fd (fd, data, data_block_size); + END_TIMING + ASSERT (ret == data_block_size); + ASSERT (memcmp (data, expected + data_block_size, data_block_size) == 0); + /* This assertion fails if data_block_size is much larger than needed + and SMALL_DELAY is too large. */ + ASSERT (spent_time < 0.5); + + break; + + default: + abort (); + } + + free (data); + free (expected); +} |