X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Scheduler%2FScheduler.cc;h=62a5dfecf55bdb2ac3f8a2ef315786dee5ff4c47;hb=331547d2a137f796eb5fcb390502aece3e01bb16;hp=21885f24a8fd26bf6add1f5c1cbb0f10cf4d91f4;hpb=c52cd7d87dbb525c1267aad27391b8b7365dbb57;p=senf.git diff --git a/Scheduler/Scheduler.cc b/Scheduler/Scheduler.cc index 21885f2..62a5dfe 100644 --- a/Scheduler/Scheduler.cc +++ b/Scheduler/Scheduler.cc @@ -71,26 +71,32 @@ #include #include #include "Utils/Exception.hh" +#include "Utils/MicroTime.hh" static const int EPollInitialSize = 16; #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// -prefix_ satcom::lib::Scheduler::Scheduler & satcom::lib::Scheduler::instance() +prefix_ senf::Scheduler::Scheduler & senf::Scheduler::instance() { static Scheduler instance; return instance; } -prefix_ satcom::lib::Scheduler::Scheduler() +prefix_ void senf::Scheduler::timeout(unsigned long timeout, TimerCallback const & cb) +{ + timerQueue_.push(TimerSpec(now()+1000*timeout,cb)); +} + +prefix_ senf::Scheduler::Scheduler() : epollFd_(epoll_create(EPollInitialSize)) { if (epollFd_<0) throw SystemException(errno); } -prefix_ void satcom::lib::Scheduler::add(int fd, Callback const & cb, EventId eventMask) +prefix_ void senf::Scheduler::do_add(int fd, SimpleCallback const & cb, int eventMask) { FdTable::iterator i (fdTable_.find(fd)); int action (EPOLL_CTL_MOD); @@ -114,7 +120,7 @@ prefix_ void satcom::lib::Scheduler::add(int fd, Callback const & cb, EventId ev throw SystemException(errno); } -prefix_ void satcom::lib::Scheduler::remove(int fd, EventId eventMask) +prefix_ void senf::Scheduler::do_remove(int fd, int eventMask) { FdTable::iterator i (fdTable_.find(fd)); if (i == fdTable_.end()) @@ -130,7 +136,7 @@ prefix_ void satcom::lib::Scheduler::remove(int fd, EventId eventMask) memset(&ev,0,sizeof(ev)); ev.events = i->second.epollMask(); ev.data.fd = fd; - + int action (EPOLL_CTL_MOD); if (ev.events==0) { action = EPOLL_CTL_DEL; @@ -141,7 +147,8 @@ prefix_ void satcom::lib::Scheduler::remove(int fd, EventId eventMask) throw SystemException(errno); } -prefix_ int satcom::lib::Scheduler::EventSpec::epollMask() + +prefix_ int senf::Scheduler::EventSpec::epollMask() const { int mask (0); @@ -153,16 +160,27 @@ prefix_ int satcom::lib::Scheduler::EventSpec::epollMask() return mask; } -prefix_ void satcom::lib::Scheduler::process() +prefix_ void senf::Scheduler::process() { terminate_ = false; while (! terminate_) { + + MicroTime timeNow = now(); + while ( ! timerQueue_.empty() && timerQueue_.top().timeout <= timeNow ) { + timerQueue_.top().cb(); + timerQueue_.pop(); + } + if (terminate_) + return; + int timeout = timerQueue_.empty() ? -1 : int((timerQueue_.top().timeout - timeNow)/1000); + struct epoll_event ev; - int events = epoll_wait(epollFd_, &ev, 1, 1000); + int events = epoll_wait(epollFd_, &ev, 1, timeout); if (events<0) // Hmm ... man epoll says, it will NOT return with EINTR ?? throw SystemException(errno); if (events==0) + // Timeout .. it will be run when reachiung the top of the loop continue; FdTable::iterator i = fdTable_.find(ev.data.fd); @@ -171,25 +189,34 @@ prefix_ void satcom::lib::Scheduler::process() if (ev.events & EPOLLIN) { BOOST_ASSERT(spec.cb_read); - spec.cb_read(ev.data.fd, EV_READ); + spec.cb_read(EV_READ); } else if (ev.events & EPOLLPRI) { BOOST_ASSERT(spec.cb_prio); - spec.cb_prio (ev.data.fd, EV_PRIO); + spec.cb_prio(EV_PRIO); } else if (ev.events & EPOLLOUT) { BOOST_ASSERT(spec.cb_write); - spec.cb_write(ev.data.fd, EV_WRITE); + spec.cb_write(EV_WRITE); } else if (ev.events & EPOLLHUP) { - BOOST_ASSERT(spec.cb_hup); - spec.cb_hup(ev.data.fd, EV_HUP); + if (spec.cb_hup) + spec.cb_hup(EV_HUP); + else if (ev.events & EPOLLERR) { + if (spec.cb_write) spec.cb_write(EV_HUP); + if (spec.cb_read) spec.cb_read(EV_HUP); + } } - else if (ev.events & EPOLLERR) { - BOOST_ASSERT(spec.cb_err); - spec.cb_err(ev.data.fd, EV_ERR); + else if (ev.events & EPOLLERR && ! ev.events & EPOLLHUP) { + if (spec.cb_err) + spec.cb_err(EV_ERR); + else { + if (spec.cb_write) spec.cb_write(EV_ERR); + if (spec.cb_read) spec.cb_read(EV_ERR); + } } + } } @@ -199,5 +226,5 @@ prefix_ void satcom::lib::Scheduler::process() // Local Variables: // mode: c++ -// c-file-style: "satcom" +// c-file-style: "senf" // End: