122 lines
2.5 KiB
C++
122 lines
2.5 KiB
C++
/* lw-support/src/lib/Net/Server.cpp
|
|
*
|
|
* (c)2005, Laurence Withers. Released under the GNU GPL. See file
|
|
* COPYING for more information / terms of license.
|
|
*/
|
|
|
|
namespace lw {
|
|
|
|
|
|
|
|
NetServer::NetServer()
|
|
: nsCallback(0), eventManager(0)
|
|
{
|
|
}
|
|
|
|
|
|
|
|
NetServer::~NetServer()
|
|
{
|
|
}
|
|
|
|
|
|
|
|
NetServer::Protocol NetServer::getProtocol(const NetAddress& addr)
|
|
{
|
|
const NetAddress* a = &addr;
|
|
if(dynamic_cast<const NetAddressIPv4*>(a)) return IPv4;
|
|
if(dynamic_cast<const NetAddressIPv6*>(a)) return IPv6;
|
|
throw UnknownProtocol();
|
|
}
|
|
|
|
|
|
|
|
void NetServer::registerCallback(EventManager& eventManager,
|
|
EventCallbackNetServer& callback)
|
|
{
|
|
clearCallback();
|
|
nsCallback = &callback;
|
|
this->eventManager = &eventManager;
|
|
eventManager.registerDevice(this, this, IOEventRead | IOEventError);
|
|
}
|
|
|
|
|
|
|
|
void NetServer::clearCallback()
|
|
{
|
|
if(eventManager) eventManager->ignoreDevice(this);
|
|
eventManager = 0;
|
|
nsCallback = 0;
|
|
}
|
|
|
|
|
|
|
|
void NetServer::ioReady(uint32_t flags) throw()
|
|
{
|
|
// TODO -- this really needs sorting somehow, since we no longer support
|
|
// error handling in the event loop
|
|
#if 0
|
|
// deal with errors
|
|
try {
|
|
if(flags & IOEventError) if(!nsCallback->error()) return false;
|
|
}
|
|
catch(...) { }
|
|
|
|
// deal with waiting connections
|
|
if(flags & IOEventRead) {
|
|
IODevice* netClient = 0;
|
|
while(true) {
|
|
if(!(netClient = accept())) break;
|
|
try {
|
|
if(!nsCallback->accept(netClient)) return false;
|
|
}
|
|
catch(...) { }
|
|
}
|
|
}
|
|
|
|
return true;
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
void NetServer::readBlock(int timeout, IOTimeoutMode timeoutMode)
|
|
{
|
|
try {
|
|
int timeout_remaining = timeout;
|
|
struct pollfd ufd = { fd, POLLIN, 0 };
|
|
IOCountdown countdown(this, L"readBlock()", timeout, timeoutMode);
|
|
|
|
while(true) {
|
|
switch(poll(&ufd, 1, timeout_remaining)) {
|
|
case -1:
|
|
if(errno == EINTR) break;
|
|
throw SystemError().chain(L"poll()");
|
|
|
|
case 0:
|
|
throw IOTimeout(this, L"acceptBlocking", timeout, timeoutMode, 0);
|
|
|
|
default:
|
|
// perform read
|
|
return;
|
|
}
|
|
|
|
// update timeout
|
|
if(!countdown.update(timeout_remaining))
|
|
throw IOTimeout(this, L"acceptBlocking", timeout, timeoutMode, 0);
|
|
}
|
|
}
|
|
catch(Exception& e) {
|
|
e.chain(L"IOPosixDevice::readBlock()");
|
|
throw;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
/* options for text editors
|
|
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
|
|
*/
|