]> granicus.if.org Git - pdns/commitdiff
work in progress, but needed to complete the tar.gz build
authorBert Hubert <bert.hubert@netherlabs.nl>
Wed, 26 Jan 2011 00:12:50 +0000 (00:12 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Wed, 26 Jan 2011 00:12:50 +0000 (00:12 +0000)
git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1911 d19b8d6e-7fed-0310-83ef-9ca221ded41b

pdns/pollmplexer.cc [new file with mode: 0644]

diff --git a/pdns/pollmplexer.cc b/pdns/pollmplexer.cc
new file mode 100644 (file)
index 0000000..793bfb0
--- /dev/null
@@ -0,0 +1,132 @@
+#include "mplexer.hh"
+#include "sstuff.hh"
+#include <iostream>
+#include <poll.h>
+#include "misc.hh"
+#include <boost/lexical_cast.hpp>
+#include "syncres.hh"
+#include "utility.hh" 
+#include "namespaces.hh"
+using namespace std;
+
+
+static FDMultiplexer* make()
+{
+  return new PollFDMultiplexer();
+}
+
+static struct RegisterOurselves
+{
+  RegisterOurselves() {
+    FDMultiplexer::getMultiplexerMap().insert(make_pair(1, &make));
+  }
+} doIt;
+
+void PollFDMultiplexer::addFD(callbackmap_t& cbmap, int fd, callbackfunc_t toDo, const boost::any& parameter)
+{
+  Callback cb;
+  cb.d_callback=toDo;
+  cb.d_parameter=parameter;
+  memset(&cb.d_ttd, 0, sizeof(cb.d_ttd));
+  if(cbmap.count(fd))
+    throw FDMultiplexerException("Tried to add fd "+lexical_cast<string>(fd)+ " to multiplexer twice");
+  cbmap[fd]=cb;
+}
+
+void PollFDMultiplexer::removeFD(callbackmap_t& cbmap, int fd)
+{
+  if(d_inrun && d_iter->first==fd)  // trying to remove us!
+    d_iter++;
+
+  if(!cbmap.erase(fd))
+    throw FDMultiplexerException("Tried to remove unlisted fd "+lexical_cast<string>(fd)+ " from multiplexer");
+}
+
+bool pollfdcomp(const struct pollfd& a, const struct pollfd& b)
+{
+  return a.fd < b.fd;
+}
+
+int PollFDMultiplexer::run(struct timeval* now)
+{
+  if(d_inrun) {
+    throw FDMultiplexerException("FDMultiplexer::run() is not reentrant!\n");
+  }
+  
+  vector<struct pollfd> pollfds;
+  
+  struct pollfd pollfd;
+  for(callbackmap_t::const_iterator i=d_readCallbacks.begin(); i != d_readCallbacks.end(); ++i) {
+    pollfd.fd = i->first;
+    pollfd.events = POLLIN;
+    pollfds.push_back(pollfd);
+  }
+
+  for(callbackmap_t::const_iterator i=d_writeCallbacks.begin(); i != d_writeCallbacks.end(); ++i) {
+    pollfd.fd = i->first;
+    pollfd.events = POLLOUT;
+    pollfds.push_back(pollfd);
+  }
+
+  int ret=poll(&pollfds[0], pollfds.size(), 500);
+  Utility::gettimeofday(now, 0); // MANDATORY!
+  
+  if(ret < 0 && errno!=EINTR)
+    throw FDMultiplexerException("poll returned error: "+stringerror());
+
+  d_iter=d_readCallbacks.end();
+  d_inrun=true;
+  
+  for(unsigned int n = 0; n < pollfds.size(); ++n) {  
+    if(pollfds[n].revents == POLLIN) {
+      d_iter=d_readCallbacks.find(pollfds[n].fd);
+    
+      if(d_iter != d_readCallbacks.end()) {
+        d_iter->second.d_callback(d_iter->first, d_iter->second.d_parameter);
+        continue; // so we don't refind ourselves as writable!
+      }
+    }
+    else if(pollfds[n].revents == POLLOUT) {
+      d_iter=d_writeCallbacks.find(pollfds[n].fd);
+    
+      if(d_iter != d_writeCallbacks.end()) {
+        d_iter->second.d_callback(d_iter->first, d_iter->second.d_parameter);
+      }
+    }
+  }
+  d_inrun=false;
+  return 0;
+}
+
+#if 0
+
+void acceptData(int fd, boost::any& parameter)
+{
+  cout<<"Have data on fd "<<fd<<endl;
+  Socket* sock=boost::any_cast<Socket*>(parameter);
+  string packet;
+  IPEndpoint rem;
+  sock->recvFrom(packet, rem);
+  cout<<"Received "<<packet.size()<<" bytes!\n";
+}
+
+
+int main()
+{
+  Socket s(InterNetwork, Datagram);
+  
+  IPEndpoint loc("0.0.0.0", 2000);
+  s.bind(loc);
+
+  PollFDMultiplexer sfm;
+
+  sfm.addReadFD(s.getHandle(), &acceptData, &s);
+
+  for(int n=0; n < 100 ; ++n) {
+    sfm.run();
+  }
+  sfm.removeReadFD(s.getHandle());
+  sfm.removeReadFD(s.getHandle());
+}
+#endif
+