Added optional timeout to fr::SocketSelector::wait

'Wait' will return true if a socket has received data, false if the duration has expired.
This commit is contained in:
Fred Nicolson 2016-12-11 19:55:33 +00:00
parent 3b890972d1
commit 6d33e938b6
2 changed files with 13 additions and 10 deletions

View File

@ -5,6 +5,7 @@
#ifndef FRNETLIB_SOCKETSELECTOR_H
#define FRNETLIB_SOCKETSELECTOR_H
#include <chrono>
#include "NetworkEncoding.h"
#include "Socket.h"
#include "TcpListener.h"
@ -19,9 +20,10 @@ namespace fr
/*!
* Waits for a socket to become ready.
*
* @param timeout The amount of time wait should block for before timing out.
* @return True if a socket is ready. False if it timed out.
*/
bool wait();
bool wait(std::chrono::milliseconds timeout = std::chrono::milliseconds(0));
/*!
* Adds a socket to the selector. Note that SocketSelector

View File

@ -25,18 +25,19 @@ namespace fr
max_descriptor = socket.get_socket_descriptor();
}
bool SocketSelector::wait()
bool SocketSelector::wait(std::chrono::milliseconds timeout)
{
listen_read = listen_set;
if(select(max_descriptor + 1, &listen_read, NULL, NULL, NULL) == SOCKET_ERROR)
{
//Check that we've not just timed out
if(errno == EAGAIN || errno == EWOULDBLOCK)
return true;
timeval wait_time;
wait_time.tv_sec = 0;
wait_time.tv_usec = std::chrono::duration_cast<std::chrono::microseconds>(timeout).count();
//Oops
listen_read = listen_set;
int select_result = select(max_descriptor + 1, &listen_read, NULL, NULL, timeout == std::chrono::milliseconds(0) ? NULL : &wait_time);
if(select_result == 0) //If it's timed out
return false;
else if(select_result == SOCKET_ERROR) //Else if error
throw std::logic_error("select() returned -1");
}
return true;
}