root/maint/gnulib/tests/test-nonblocking-reader.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. full_read
  2. full_read_from_nonblocking_fd
  3. main_reader_loop

   1 /* The reader part of a test program for non-blocking communication.
   2 
   3    Copyright (C) 2011-2021 Free Software Foundation, Inc.
   4 
   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.
   9 
  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.
  14 
  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/>.  */
  17 
  18 /* This program implements 4 tests:
  19 
  20    test == 0:
  21      Test blocking write() with blocking read().
  22 
  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)
  28 
  29    test == 1:
  30      Test non-blocking write() with blocking read().
  31 
  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)
  40 
  41    test == 2:
  42      Test blocking write() with non-blocking read().
  43 
  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)
  50 
  51    test == 3:
  52      Test non-blocking write() with non-blocking read().
  53  */
  54 
  55 #include "test-nonblocking-misc.h"
  56 
  57 static ssize_t
  58 full_read (size_t fd, void *buf, size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
  59 {
  60   size_t bytes_read;
  61 
  62   bytes_read = 0;
  63   while (bytes_read < count)
  64     {
  65       TIMING_DECLS
  66       ssize_t ret;
  67       int saved_errno;
  68 
  69       dbgfprintf (stderr, "%s: >> read (%lu)\n", PROG_ROLE,
  70                   (unsigned long) (count - bytes_read));
  71       START_TIMING
  72       ret = read (fd, (char *) buf + bytes_read, count - bytes_read);
  73       saved_errno = errno;
  74       END_TIMING
  75       dbgfprintf (stderr, "%s: << read -> %ld%s\n", PROG_ROLE,
  76                   (long) ret, dbgstrerror (ret < 0, saved_errno));
  77       if (ret < 0)
  78         return -1;
  79       else
  80         {
  81           ASSERT (ret > 0);
  82           bytes_read += ret;
  83         }
  84     }
  85   return bytes_read;
  86 }
  87 
  88 static ssize_t
  89 full_read_from_nonblocking_fd (size_t fd, void *buf, size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
  90 {
  91   size_t bytes_read;
  92 
  93   bytes_read = 0;
  94   while (bytes_read < count)
  95     {
  96       TIMING_DECLS
  97       ssize_t ret;
  98       int saved_errno;
  99 
 100       dbgfprintf (stderr, "%s: >> read (%lu)\n", PROG_ROLE,
 101                   (unsigned long) (count - bytes_read));
 102       START_TIMING
 103       ret = read (fd, (char *) buf + bytes_read, count - bytes_read);
 104       saved_errno = errno;
 105       END_TIMING
 106       dbgfprintf (stderr, "%s: << read -> %ld%s\n", PROG_ROLE,
 107                   (long) ret, dbgstrerror (ret < 0, saved_errno));
 108       /* This assertion fails if the non-blocking flag is effectively not set
 109          on fd.  */
 110       ASSERT (spent_time < 0.5);
 111       if (ret < 0)
 112         {
 113           ASSERT (saved_errno == EAGAIN || saved_errno == EWOULDBLOCK);
 114           usleep (SMALL_DELAY);
 115         }
 116       else
 117         {
 118           ASSERT (ret > 0);
 119           bytes_read += ret;
 120         }
 121     }
 122   return bytes_read;
 123 }
 124 
 125 /* Execute the reader loop.  */
 126 static void
 127 main_reader_loop (int test, size_t data_block_size, int fd)
     /* [previous][next][first][last][top][bottom][index][help] */
 128 {
 129   unsigned char *expected;
 130   unsigned char *data;
 131 
 132   /* Set up the expected data.  */
 133   expected = init_data (data_block_size);
 134 
 135   data = (unsigned char *) malloc (2 * data_block_size);
 136   ASSERT (data != NULL);
 137 
 138   switch (test)
 139     {
 140     TIMING_DECLS
 141     ssize_t ret;
 142 
 143     case 0: /* Test blocking write() with blocking read().  */
 144     case 1: /* Test non-blocking write() with blocking read().  */
 145       START_TIMING
 146       ret = full_read (fd, data, data_block_size);
 147       END_TIMING
 148       ASSERT (ret == data_block_size);
 149       ASSERT (memcmp (data, expected, data_block_size) == 0);
 150       ASSERT (spent_time > 0.5);
 151       /* This assertion fails if data_block_size is very large and
 152          ENABLE_DEBUGGING is 1.  */
 153       ASSERT (spent_time < 1.5);
 154 
 155       usleep (1000000);
 156 
 157       START_TIMING
 158       ret = full_read (fd, data, data_block_size);
 159       END_TIMING
 160       ASSERT (ret == data_block_size);
 161       ASSERT (memcmp (data, expected + data_block_size, data_block_size) == 0);
 162       /* This assertion fails if data_block_size is much larger than needed
 163          and SMALL_DELAY is too large.  */
 164       ASSERT (spent_time < 0.5);
 165 
 166       break;
 167 
 168     case 2: /* Test blocking write() with non-blocking read().  */
 169     case 3: /* Test non-blocking write() with non-blocking read().  */
 170       START_TIMING
 171       ret = full_read_from_nonblocking_fd (fd, data, data_block_size);
 172       END_TIMING
 173       ASSERT (ret == data_block_size);
 174       ASSERT (memcmp (data, expected, data_block_size) == 0);
 175       ASSERT (spent_time > 0.5);
 176       /* This assertion fails if data_block_size is much larger than needed
 177          and SMALL_DELAY is too large, or if data_block_size is very large and
 178          ENABLE_DEBUGGING is 1.  */
 179       ASSERT (spent_time < 1.5);
 180 
 181       usleep (1000000);
 182 
 183       START_TIMING
 184       ret = full_read_from_nonblocking_fd (fd, data, data_block_size);
 185       END_TIMING
 186       ASSERT (ret == data_block_size);
 187       ASSERT (memcmp (data, expected + data_block_size, data_block_size) == 0);
 188       /* This assertion fails if data_block_size is much larger than needed
 189          and SMALL_DELAY is too large.  */
 190       ASSERT (spent_time < 0.5);
 191 
 192       break;
 193 
 194     default:
 195       abort ();
 196     }
 197 
 198   free (data);
 199   free (expected);
 200 }

/* [previous][next][first][last][top][bottom][index][help] */