Merge remote-tracking branch 'origin/topic/jsiwek/improve_comm_loop'

* origin/topic/jsiwek/improve_comm_loop:
  Add a simple FD_Set wrapper/helper class.
  Fix Pipe copy/assignment to make a copy of flags.
  Fix possible abort on writing to a full pipe.
  Remove timeouts from remote communication loop.
This commit is contained in:
Robin Sommer 2014-09-25 12:46:39 -07:00
commit e9692958f0
22 changed files with 448 additions and 65 deletions

View file

@ -1367,12 +1367,14 @@ void RemoteSerializer::Unregister(ID* id)
}
}
void RemoteSerializer::GetFds(int* read, int* write, int* except)
void RemoteSerializer::GetFds(iosource::FD_Set* read, iosource::FD_Set* write,
iosource::FD_Set* except)
{
*read = io->Fd();
read->Insert(io->Fd());
read->Insert(io->ExtraReadFDs());
if ( io->CanWrite() )
*write = io->Fd();
write->Insert(io->Fd());
}
double RemoteSerializer::NextTimestamp(double* local_network_time)
@ -3355,6 +3357,15 @@ SocketComm::~SocketComm()
static unsigned int first_rtime = 0;
static void fd_vector_set(const std::vector<int>& fds, fd_set* set, int* max)
{
for ( size_t i = 0; i < fds.size(); ++i )
{
FD_SET(fds[i], set);
*max = ::max(fds[i], *max);
}
}
void SocketComm::Run()
{
first_rtime = (unsigned int) current_time(true);
@ -3376,10 +3387,9 @@ void SocketComm::Run()
FD_ZERO(&fd_write);
FD_ZERO(&fd_except);
int max_fd = 0;
int max_fd = io->Fd();
FD_SET(io->Fd(), &fd_read);
max_fd = io->Fd();
max_fd = std::max(max_fd, io->ExtraReadFDs().Set(&fd_read));
loop_over_list(peers, i)
{
@ -3388,6 +3398,8 @@ void SocketComm::Run()
FD_SET(peers[i]->io->Fd(), &fd_read);
if ( peers[i]->io->Fd() > max_fd )
max_fd = peers[i]->io->Fd();
max_fd = std::max(max_fd,
peers[i]->io->ExtraReadFDs().Set(&fd_read));
}
else
{
@ -3438,38 +3450,17 @@ void SocketComm::Run()
if ( ! io->IsFillingUp() && shutting_conns_down )
shutting_conns_down = false;
// We cannot rely solely on select() as the there may
// be some data left in our input/output queues. So, we use
// a small timeout for select and check for data
// manually afterwards.
static long selects = 0;
static long canwrites = 0;
static long timeouts = 0;
++selects;
if ( io->CanWrite() )
++canwrites;
// FIXME: Fine-tune this (timeouts, flush, etc.)
struct timeval small_timeout;
small_timeout.tv_sec = 0;
small_timeout.tv_usec =
io->CanWrite() || io->CanRead() ? 1 : 10;
#if 0
if ( ! io->CanWrite() )
usleep(10);
#endif
int a = select(max_fd + 1, &fd_read, &fd_write, &fd_except,
&small_timeout);
if ( a == 0 )
++timeouts;
int a = select(max_fd + 1, &fd_read, &fd_write, &fd_except, 0);
if ( selects % 100000 == 0 )
Log(fmt("selects=%ld canwrites=%ld timeouts=%ld", selects, canwrites, timeouts));
Log(fmt("selects=%ld canwrites=%ld", selects, canwrites));
if ( a < 0 )
// Ignore errors for now.