void FdReader::Run()

in simulation/src/core/model/unix-fd-reader.cc [163:233]


void FdReader::Run (void)
{
  NS_LOG_FUNCTION (this);
  int nfds;
  fd_set rfds;

  nfds = (m_fd > m_evpipe[0] ? m_fd : m_evpipe[0]) + 1;

  FD_ZERO (&rfds);
  FD_SET (m_fd, &rfds);
  FD_SET (m_evpipe[0], &rfds);

  for (;;)
    {
      int r;
      fd_set readfds = rfds;

      r = select (nfds, &readfds, NULL, NULL, NULL);
      if (r == -1 && errno != EINTR)
        {
          NS_FATAL_ERROR ("select() failed: " << std::strerror (errno));
        }

      if (FD_ISSET (m_evpipe[0], &readfds))
        {
          // drain the event pipe
          for (;;)
            {
              char buf[1024];
              ssize_t len = read (m_evpipe[0], buf, sizeof (buf));
              if (len == 0)
                {
                  NS_FATAL_ERROR ("event pipe closed");
                }
              if (len < 0)
                {
                  if (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK)
                    {
                      break;
                    }
                  else
                    {
                      NS_FATAL_ERROR ("read() failed: " << std::strerror (errno));
                    }
                }
            }
        }

      if (m_stop)
        {
          // this thread is done
          break;
        }

      if (FD_ISSET (m_fd, &readfds))
        {
          struct FdReader::Data data = DoRead ();
          // reading stops when m_len is zero
          if (data.m_len == 0)
            {
              break;
            }
          // the callback is only called when m_len is positive (data
          // is ignored if m_len is negative)
          else if (data.m_len > 0)
            {
              m_readCallback (data.m_buf, data.m_len);
            }
        }
    }
}