diff --git a/include/SocketSelector.h b/include/SocketSelector.h index 7a9fe7c..4541b3a 100644 --- a/include/SocketSelector.h +++ b/include/SocketSelector.h @@ -5,6 +5,7 @@ #ifndef FRNETLIB_SOCKETSELECTOR_H #define FRNETLIB_SOCKETSELECTOR_H +#include #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 diff --git a/src/SocketSelector.cpp b/src/SocketSelector.cpp index 2b24644..2925b94 100644 --- a/src/SocketSelector.cpp +++ b/src/SocketSelector.cpp @@ -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(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; }