From c4c08d4da529feee37dbf0b6e02719561f7da1a5 Mon Sep 17 00:00:00 2001 From: Bert Hubert Date: Wed, 19 Apr 2006 06:52:30 +0000 Subject: [PATCH] first shot at solaris completion ports multiplexer - wrote it on linux so it won't work yet git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@734 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- pdns/epollmplexer.cc | 3 - pdns/portsmplexer.cc | 153 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+), 3 deletions(-) create mode 100644 pdns/portsmplexer.cc diff --git a/pdns/epollmplexer.cc b/pdns/epollmplexer.cc index 608d7d8ce..d1cbcb72f 100644 --- a/pdns/epollmplexer.cc +++ b/pdns/epollmplexer.cc @@ -12,9 +12,6 @@ using namespace boost; using namespace std; -#include - - class EpollFDMultiplexer : public FDMultiplexer { public: diff --git a/pdns/portsmplexer.cc b/pdns/portsmplexer.cc new file mode 100644 index 000000000..68628c171 --- /dev/null +++ b/pdns/portsmplexer.cc @@ -0,0 +1,153 @@ +#include "mplexer.hh" +#include "sstuff.hh" +#include +#include +#include "misc.hh" +#include +#include "syncres.hh" +#include +using namespace boost; +using namespace std; + + +class PortsFDMultiplexer : public FDMultiplexer +{ +public: + PortsFDMultiplexer(); + virtual ~PortsFDMultiplexer() + { + port_close(d_portfd); + } + + virtual int run(struct timeval* tv); + + virtual void addFD(callbackmap_t& cbmap, int fd, callbackfunc_t toDo, const boost::any& parameter); + virtual void removeFD(callbackmap_t& cbmap, int fd); + string getName() + { + return "solaris completion ports"; + } +private: + int d_portfd; + boost::shared_array d_pevents; + static int s_maxevents; // not a hard maximum +}; + + +static FDMultiplexer* makePorts() +{ + return new PortsFDMultiplexer(); +} + +static struct PortsRegisterOurselves +{ + PortsRegisterOurselves() { + FDMultiplexer::getMultiplexerMap().insert(make_pair(0, &makePorts)); // priority 0! + } +} doItPorts; + + +int PortsFDMultiplexer::s_maxevents=1024; +PortsFDMultiplexer::PortsFDMultiplexer() : d_pevents(new port_event_t[s_maxevents]) +{ + d_portfd=port_create(); // not hard max + if(d_portfd < 0) + throw FDMultiplexerException("Setting up port: "+stringerror()); +} + +void PortsFDMultiplexer::addFD(callbackmap_t& cbmap, int fd, callbackfunc_t toDo, const boost::any& parameter) +{ + accountingAddFD(cbmap, fd, toDo, parameter); + + if(port_associate(port, PORT_SOURCE_FD, fd, (&cbmap == &d_readCallbacks) ? POLLIN : POLLOUT, 0) < 0) { + cbmap.erase(fd); + throw FDMultiplexerException("Adding fd to port set: "+stringerror()); + } +} + +void PortsFDMultiplexer::removeFD(callbackmap_t& cbmap, int fd) +{ + if(!cbmap.erase(fd)) + throw FDMultiplexerException("Tried to remove unlisted fd "+lexical_cast(fd)+ " from multiplexer"); + + if(port_dissociate(port, PORT_SOURCE_FD, fd) < 0) + throw FDMultiplexerException("Removing fd from port set: "+stringerror()); +} + +int PortsFDMultiplexer::run(struct timeval* now) +{ + if(d_inrun) { + throw FDMultiplexerException("FDMultiplexer::run() is not reentrant!\n"); + } + + struct timeval tv; + tv.tv_sec=0; tv.tv_usec=500000; + int numevents=0; + int ret= port_getn(d_portfd, d_pevents, min(PORT_MAX_LIST, s_maxevents), &numevents, &timeout); + + gettimeofday(now,0); + + if(ret < 0 && errno!=EINTR) + throw FDMultiplexerException("completion port_getn returned error: "+stringerror()); + + if(ret==0) // nothing + return 0; + + d_inrun=true; + + for(int n=0; n < numevents; ++n) { + d_iter=d_readCallbacks.find(d_portevents[n].portev_object); + + if(d_iter != d_readCallbacks.end()) { + d_iter->second.d_callback(d_iter->first, d_iter->second.d_parameter); + result = port_associate(d_portfd, PORT_SOURCE_FD, d_portevents[n].portev_object, + POLLIN, d_pevents[n].portev_user); + } + + d_iter=d_writeCallbacks.find(d_pevents[n].data.fd); + + if(d_iter != d_writeCallbacks.end()) { + d_iter->second.d_callback(d_iter->first, d_iter->second.d_parameter); + result = port_associate(d_portfd, PORT_SOURCE_FD, d_portevents[n].portev_object, + POLLOUT, d_pevents[n].portev_user); + } + + + } + + d_inrun=false; + return 0; +} + +#if 0 +void acceptData(int fd, boost::any& parameter) +{ + cout<<"Have data on fd "<(parameter); + string packet; + IPEndpoint rem; + sock->recvFrom(packet, rem); + cout<<"Received "<