lw-support/src/liblw-support/Net/Server.cpp

122 lines
2.5 KiB
C++
Raw Normal View History

2006-08-25 00:09:46 +01:00
/* 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;
*/