-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #88 from polserver/network-improvements
Network improvements
- Loading branch information
Showing
67 changed files
with
654 additions
and
854 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
#pragma once | ||
#ifndef H_SINGLEPOLLER | ||
#define H_SINGLEPOLLER | ||
|
||
#include "sockets.h" | ||
|
||
#include "singlepollers/pollingwithpoll.h" | ||
//#include "singlepollers/pollingwithselect.h" | ||
|
||
namespace Pol | ||
{ | ||
namespace Clib | ||
{ | ||
// This only works for Linux and Windows more recent than Windows Vista / Windows Server 2008. Let | ||
// us know if anyone still needs Windows XP support (PollingWithSelect). If no one complains, we | ||
// should remove pollingwithselect in the near future. | ||
using PollingStrategy = PollingWithPoll; | ||
|
||
class SinglePoller | ||
{ | ||
public: | ||
explicit SinglePoller( SOCKET socket ) : poller( socket ){}; | ||
|
||
int wait_for_events() { return poller.wait_for_events(); } | ||
|
||
// Note that not every poller will support usec resolution. I should find a way around it. | ||
void set_timeout( int timeout_sec, int timeout_usec ) | ||
{ | ||
poller.set_timeout( timeout_sec, timeout_usec ); | ||
} | ||
|
||
bool incoming() { return poller.incoming(); } | ||
bool error() { return poller.error(); } | ||
bool writable() { return poller.writable(); } | ||
|
||
bool prepare( bool notify_writable ) | ||
{ | ||
if ( !poller.valid_socket() ) | ||
return false; | ||
|
||
poller.reset(); | ||
poller.notify_on_incoming(); | ||
poller.notify_on_error(); | ||
if ( notify_writable ) | ||
poller.notify_on_writable(); | ||
|
||
return true; | ||
} | ||
|
||
private: | ||
PollingStrategy poller; | ||
}; | ||
} // namespace Clib | ||
} // namespace Pol | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
#pragma once | ||
#ifndef H_POLLINGWITHPOLL | ||
#define H_POLLINGWITHPOLL | ||
|
||
#include "../../passert.h" | ||
#include "../sockets.h" | ||
|
||
#ifdef _WIN32 | ||
|
||
// compatibility wrapper for windows | ||
int poll( struct pollfd* fds, ULONG nfds, int timeout ) | ||
{ | ||
return WSAPoll( fds, nfds, timeout ); | ||
}; | ||
|
||
#else | ||
|
||
#include <poll.h> | ||
|
||
#endif | ||
|
||
namespace Pol | ||
{ | ||
namespace Clib | ||
{ | ||
class PollingWithPoll | ||
{ | ||
public: | ||
explicit PollingWithPoll( SOCKET socket ) | ||
: default_timeout{0, 0}, processed( false ) | ||
{ | ||
fdList.fd = socket; | ||
reset(); | ||
} | ||
|
||
void reset() | ||
{ | ||
processed = false; | ||
|
||
fdList.events = 0; | ||
fdList.revents = 0; | ||
} | ||
|
||
void notify_on_incoming() { fdList.events |= POLLIN; } | ||
void notify_on_error() {} // do nothing, poll() always notifies on error | ||
void notify_on_writable() { fdList.events |= POLLOUT; } | ||
|
||
bool incoming() { return ( processed ) ? ( (fdList.revents & POLLIN) != 0 ) : false; } | ||
bool error() { return ( processed ) ? ( ( fdList.revents & POLLERR ) != 0 ) : false; } | ||
bool writable() { return ( processed ) ? ( ( fdList.revents & POLLOUT ) != 0 ) : false; } | ||
|
||
void set_timeout( int timeout_sec, int timeout_usec ) | ||
{ | ||
default_timeout.tv_sec = timeout_sec; | ||
default_timeout.tv_usec = timeout_usec; | ||
} | ||
|
||
int wait_for_events() | ||
{ | ||
passert( valid_socket() ); | ||
|
||
// ugly conversion, maybe change everything to use ms | ||
int timeout_ms = 1000 * default_timeout.tv_sec + default_timeout.tv_usec / 1000; | ||
|
||
// if timeout is non-zero but below 1ms, cap at 1ms | ||
if ( default_timeout.tv_usec != 0 && timeout_ms == 0 ) | ||
timeout_ms = 1; | ||
|
||
int res = poll( &fdList, 1, timeout_ms ); | ||
|
||
// only mark as processed if we don't have errors | ||
if ( res >= 0 ) | ||
processed = true; | ||
|
||
return res; | ||
} | ||
|
||
bool valid_socket() { return fdList.fd != INVALID_SOCKET; } | ||
|
||
private: | ||
pollfd fdList; // a list of 1, this is a single poller | ||
|
||
timeval default_timeout; | ||
bool processed; | ||
}; | ||
} // namespace Clib | ||
} // namespace Pol | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
#pragma once | ||
#ifndef H_POLLINGWITHSELECT | ||
#define H_POLLINGWITHSELECT | ||
|
||
#include "../../passert.h" | ||
#include "../sockets.h" | ||
|
||
namespace Pol | ||
{ | ||
namespace Clib | ||
{ | ||
class PollingWithSelect | ||
{ | ||
public: | ||
explicit PollingWithSelect( SOCKET socket ) | ||
: socket( socket ), default_timeout{0, 0}, processed( false ) | ||
{ | ||
reset(); | ||
} | ||
|
||
void reset() | ||
{ | ||
processed = false; | ||
FD_ZERO( &c_recv_fd ); | ||
FD_ZERO( &c_err_fd ); | ||
FD_ZERO( &c_send_fd ); | ||
} | ||
|
||
void notify_on_incoming() { FD_SET( socket, &c_recv_fd ); } | ||
void notify_on_error() { FD_SET( socket, &c_err_fd ); } | ||
void notify_on_writable() { FD_SET( socket, &c_send_fd ); } | ||
|
||
bool incoming() { return ( processed ) ? FD_ISSET( socket, &c_recv_fd ) : false; } | ||
bool error() { return ( processed ) ? FD_ISSET( socket, &c_err_fd ) : false; } | ||
bool writable() { return ( processed ) ? FD_ISSET( socket, &c_send_fd ) : false; } | ||
|
||
void set_timeout( int timeout_sec, int timeout_usec ) | ||
{ | ||
default_timeout.tv_sec = timeout_sec; | ||
default_timeout.tv_usec = timeout_usec; | ||
} | ||
|
||
int wait_for_events() | ||
{ | ||
passert( valid_socket() ); | ||
|
||
// Linux requires nfds to be the largest descriptor + 1, Windows doesn't care | ||
const int nfds = socket + 1; | ||
timeval c_select_timeout = default_timeout; | ||
|
||
int res = select( nfds, &c_recv_fd, &c_send_fd, &c_err_fd, &c_select_timeout ); | ||
|
||
// only mark as processed if we don't have errors, otherwise the sets are the same as we | ||
// provided | ||
if ( res >= 0 ) | ||
processed = true; | ||
|
||
return res; | ||
} | ||
|
||
bool valid_socket() | ||
{ | ||
#ifndef _WIN32 | ||
// Linux and other non-windows OS can't handle FDs larger than FD_SETSIZE when using select() | ||
return socket != INVALID_SOCKET && socket < FD_SETSIZE; | ||
#else | ||
return socket != INVALID_SOCKET; | ||
#endif | ||
} | ||
|
||
private: | ||
fd_set c_recv_fd; | ||
fd_set c_err_fd; | ||
fd_set c_send_fd; | ||
|
||
SOCKET socket; | ||
timeval default_timeout; | ||
bool processed; | ||
}; | ||
} // namespace Clib | ||
} // namespace Pol | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.