#include <unistd.h>
#include "misc.hh"
#include <sys/types.h>
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)
#include <sys/event.h>
#endif
#include <sys/time.h>
close(d_kqueuefd);
}
- virtual int run(struct timeval* tv, int timeout=500);
+ virtual int run(struct timeval* tv, int timeout=500) override;
+ virtual void getAvailableFDs(std::vector<int>& fds, int timeout) override;
- 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()
+ virtual void addFD(callbackmap_t& cbmap, int fd, callbackfunc_t toDo, const boost::any& parameter, const struct timeval* ttd=nullptr) override;
+ virtual void removeFD(callbackmap_t& cbmap, int fd) override;
+ string getName() const override
{
return "kqueue";
}
throw FDMultiplexerException("Setting up kqueue: "+stringerror());
}
-void KqueueFDMultiplexer::addFD(callbackmap_t& cbmap, int fd, callbackfunc_t toDo, const boost::any& parameter)
+void KqueueFDMultiplexer::addFD(callbackmap_t& cbmap, int fd, callbackfunc_t toDo, const boost::any& parameter, const struct timeval* ttd)
{
- accountingAddFD(cbmap, fd, toDo, parameter);
+ accountingAddFD(cbmap, fd, toDo, parameter, ttd);
struct kevent kqevent;
EV_SET(&kqevent, fd, (&cbmap == &d_readCallbacks) ? EVFILT_READ : EVFILT_WRITE, EV_ADD, 0,0,0);
-
+
if(kevent(d_kqueuefd, &kqevent, 1, 0, 0, 0) < 0) {
cbmap.erase(fd);
throw FDMultiplexerException("Adding fd to kqueue set: "+stringerror());
throw FDMultiplexerException("Removing fd from kqueue set: "+stringerror());
}
+void KqueueFDMultiplexer::getAvailableFDs(std::vector<int>& fds, int timeout)
+{
+ struct timespec ts;
+ ts.tv_sec=timeout/1000;
+ ts.tv_nsec=(timeout % 1000) * 1000000;
+
+ int ret = kevent(d_kqueuefd, 0, 0, d_kevents.get(), s_maxevents, &ts);
+
+ if(ret < 0 && errno != EINTR)
+ throw FDMultiplexerException("kqueue returned error: "+stringerror());
+
+ for(int n=0; n < ret; ++n) {
+ fds.push_back(d_kevents[n].ident);
+ }
+}
+
int KqueueFDMultiplexer::run(struct timeval* now, int timeout)
{
if(d_inrun) {
int ret=kevent(d_kqueuefd, 0, 0, d_kevents.get(), s_maxevents, &ts);
gettimeofday(now,0); // MANDATORY!
-
+
if(ret < 0 && errno!=EINTR)
throw FDMultiplexerException("kqueue returned error: "+stringerror());
for(int n=0; n < ret; ++n) {
d_iter=d_readCallbacks.find(d_kevents[n].ident);
if(d_iter != d_readCallbacks.end()) {
- d_iter->second.d_callback(d_iter->first, d_iter->second.d_parameter);
+ d_iter->d_callback(d_iter->d_fd, d_iter->d_parameter);
continue; // so we don't find ourselves as writable again
}
d_iter=d_writeCallbacks.find(d_kevents[n].ident);
if(d_iter != d_writeCallbacks.end()) {
- d_iter->second.d_callback(d_iter->first, d_iter->second.d_parameter);
+ d_iter->d_callback(d_iter->d_fd, d_iter->d_parameter);
}
}