/* The reader part of a test program for non-blocking communication.

   Copyright (C) 2011-2020 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 <https://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 || saved_errno == EWOULDBLOCK);
          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);
}
