/* 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(a)) return IPv4; if(dynamic_cast(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; */