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

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

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. main_writer_loop

   1 /* The writer 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 /* 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,
     /* [previous][next][first][last][top][bottom][index][help] */
  61                   bool has_large_buffer)
  62 {
  63   int too_small = 0;
  64   unsigned char *data;
  65 
  66   /* Set up the data to transfer.  */
  67   data = init_data (data_block_size);
  68 
  69   switch (test)
  70     {
  71     TIMING_DECLS
  72     ssize_t ret;
  73 
  74     case 0: /* Test blocking write() with blocking read().  */
  75     case 2: /* Test blocking write() with non-blocking read().  */
  76       {
  77         int saved_errno;
  78 
  79         usleep (1000000);
  80 
  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)
  91           {
  92             /* This assertion fails if data_block_size is too small.  */
  93             if (!(spent_time > 0.5))
  94               {
  95                 fprintf (stderr,
  96                          "%s:1: spent_time = %g, data_block_size too small\n",
  97                          PROG_ROLE, spent_time);
  98                 too_small = 1;
  99               }
 100           }
 101         ASSERT (spent_time < 1.5);
 102       }
 103       break;
 104 
 105     case 1: /* Test non-blocking write() with blocking read().  */
 106     case 3: /* Test non-blocking write() with non-blocking read().  */
 107       {
 108         size_t bytes_written;
 109         int saved_errno;
 110 
 111         usleep (1000000);
 112 
 113         bytes_written = 0;
 114         while (bytes_written < 2 * data_block_size)
 115           {
 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)
 126               {
 127                 ASSERT (saved_errno == EAGAIN || saved_errno == EWOULDBLOCK);
 128                 ASSERT (spent_time < 0.5);
 129                 break;
 130               }
 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)
 135               {
 136                 ASSERT (saved_errno == EAGAIN || saved_errno == EWOULDBLOCK);
 137                 usleep (SMALL_DELAY);
 138               }
 139             else
 140               {
 141                 /* This assertion fails if data_block_size is too small.  */
 142                 if (!(ret > 0))
 143                   {
 144                     fprintf (stderr,
 145                              "%s:1: spent_time = %g, data_block_size too small\n",
 146                              PROG_ROLE, spent_time);
 147                     too_small = 1;
 148                   }
 149                 bytes_written += ret;
 150               }
 151           }
 152         ASSERT (bytes_written >= data_block_size);
 153 
 154         while (bytes_written < 2 * data_block_size)
 155           {
 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)
 167               {
 168                 ASSERT (saved_errno == EAGAIN || saved_errno == EWOULDBLOCK);
 169                 usleep (SMALL_DELAY);
 170               }
 171             else
 172               {
 173                 ASSERT (ret > 0);
 174                 bytes_written += ret;
 175               }
 176           }
 177       }
 178       break;
 179 
 180     default:
 181       abort ();
 182     }
 183 
 184   free (data);
 185   return too_small;
 186 }

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