X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Scheduler%2FTimerEvent.cc;h=437aae34ddcf0587604ec239c79e7f8eeac69174;hb=bd9f9d3fd6fbcff0112a7bf48ab9284da9576b11;hp=7c3278bd85632ee409e05ed4feb1c0b5418a21fb;hpb=03516e8371a90f908ce54dedb3c874eec7dd08ff;p=senf.git diff --git a/Scheduler/TimerEvent.cc b/Scheduler/TimerEvent.cc index 7c3278b..437aae3 100644 --- a/Scheduler/TimerEvent.cc +++ b/Scheduler/TimerEvent.cc @@ -27,59 +27,28 @@ #include "TimerEvent.ih" // Custom includes +#include //#include "TimerEvent.mpp" #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// prefix_ senf::scheduler::detail::TimerDispatcher::TimerDispatcher() - : blocked_ (true) -{ - if (pipe(timerPipe_) < 0) - SENF_THROW_SYSTEM_EXCEPTION("pipe()"); - senf::scheduler::FdManager::instance().set(timerPipe_[0], FdManager::EV_READ, this); - - sigemptyset(&sigSet_); - sigaddset(&sigSet_, SIGALRM); - sigprocmask(SIG_BLOCK, &sigSet_, 0); - - struct sigaction act; - act.sa_sigaction = &sigHandler; - act.sa_mask = sigSet_; - act.sa_flags = SA_SIGINFO | SA_RESTART; - if (sigaction(SIGALRM, &act, 0) < 0) - SENF_THROW_SYSTEM_EXCEPTION("sigaction()"); - - struct sigevent ev; - ::memset(&ev, 0, sizeof(ev)); - ev.sigev_notify = SIGEV_SIGNAL; - ev.sigev_signo = SIGALRM; - ev.sigev_value.sival_ptr = this; - if (timer_create(CLOCK_MONOTONIC, &ev, &timerId_) < 0) - SENF_THROW_SYSTEM_EXCEPTION("timer_create()"); -} + : source_ (new PollTimerSource()) +{} prefix_ senf::scheduler::detail::TimerDispatcher::~TimerDispatcher() { TimerSet::iterator i (timers_.begin()); TimerSet::iterator const i_end (timers_.end()); for (; i != i_end; ++i) - senf::scheduler::FIFORunner::instance().dequeue(&(*i)); - - timer_delete(timerId_); - ::signal(SIGALRM, SIG_IGN); - sigprocmask(SIG_UNBLOCK, &sigSet_, 0); - senf::scheduler::FdManager::instance().remove(timerPipe_[0]); - close(timerPipe_[0]); - close(timerPipe_[1]); + senf::scheduler::detail::FIFORunner::instance().dequeue(&(*i)); } void senf::scheduler::detail::TimerDispatcher::add(TimerEvent & event) { TimerSet::iterator i (timers_.insert(event)); - senf::scheduler::FIFORunner::instance().enqueue(&(*i)); - if (! blocked_) - reschedule(); + senf::scheduler::detail::FIFORunner::instance().enqueue(&(*i)); } prefix_ void senf::scheduler::detail::TimerDispatcher::remove(TimerEvent & event) @@ -87,88 +56,52 @@ prefix_ void senf::scheduler::detail::TimerDispatcher::remove(TimerEvent & event TimerSet::iterator i (TimerSet::current(event)); if (i == timers_.end()) return; - senf::scheduler::FIFORunner::instance().dequeue(&(*i)); + senf::scheduler::detail::FIFORunner::instance().dequeue(&(*i)); timers_.erase(i); - if (! blocked_) - reschedule(); -} - -prefix_ void senf::scheduler::detail::TimerDispatcher::blockSignals() -{ - if (blocked_) - return; - sigprocmask(SIG_BLOCK, &sigSet_, 0); - blocked_ = true; } -prefix_ void senf::scheduler::detail::TimerDispatcher::unblockSignals() +prefix_ void senf::scheduler::detail::TimerDispatcher::prepareRun() { - if (! blocked_) - return; - reschedule(); - sigprocmask(SIG_UNBLOCK, &sigSet_, 0); - blocked_ = false; -} - -prefix_ void senf::scheduler::detail::TimerDispatcher::signal(int events) -{ - siginfo_t info; - if (read(timerPipe_[0], &info, sizeof(info)) < int(sizeof(info))) - return; TimerSet::iterator i (timers_.begin()); TimerSet::iterator const i_end (timers_.end()); - ClockService::clock_type now (senf::scheduler::FdManager::instance().eventTime()); + ClockService::clock_type now (senf::scheduler::detail::FdManager::instance().eventTime()); for (; i != i_end && i->timeout_ <= now ; ++i) i->setRunnable(); } -prefix_ void senf::scheduler::detail::TimerDispatcher::sigHandler(int signal, - ::siginfo_t * siginfo, - void *) -{ - // The manpage says, si_signo is unused in linux so we set it here - siginfo->si_signo = signal; - // We can't do much on error anyway so we ignore errors here - if (siginfo->si_value.sival_ptr == 0) - return; - write(static_cast(siginfo->si_value.sival_ptr)->timerPipe_[1], - siginfo, sizeof(*siginfo)); -} - prefix_ void senf::scheduler::detail::TimerDispatcher::reschedule() { - struct itimerspec timer; - memset(&timer, 0, sizeof(timer)); - timer.it_interval.tv_sec = 0; - timer.it_interval.tv_nsec = 0; - if (timers_.empty()) { - SENF_LOG( (senf::log::VERBOSE)("Timer disabled") ); - timer.it_value.tv_sec = 0; - timer.it_value.tv_nsec = 0; - } - else { - ClockService::clock_type next (timers_.begin()->timeout_); - if (next <= 0) - next = 1; - timer.it_value.tv_sec = ClockService::in_seconds(next); - timer.it_value.tv_nsec = ClockService::in_nanoseconds( - next - ClockService::seconds(timer.it_value.tv_sec)); - SENF_LOG( (senf::log::VERBOSE)("Next timeout scheduled @" << timer.it_value.tv_sec << "." - << std::setw(9) << std::setfill('0') << timer.it_value.tv_nsec) ); - } - if (timer_settime(timerId_, TIMER_ABSTIME, &timer, 0)<0) - SENF_THROW_SYSTEM_EXCEPTION("timer_settime()"); + if (timers_.empty()) + source_->notimeout(); + else + source_->timeout(timers_.begin()->timeout_); } /////////////////////////////////////////////////////////////////////////// // senf::scheduler::detail::TimerDispatcher::TimerEvent -prefix_ void senf::scheduler::TimerEvent::run() +prefix_ void senf::scheduler::TimerEvent::v_run() { disable(); cb_(); } +prefix_ char const * senf::scheduler::TimerEvent::v_type() + const +{ + return "tm"; +} + +prefix_ std::string senf::scheduler::TimerEvent::v_info() + const +{ + std::stringstream ss; + ss.imbue( std::locale(ss.getloc(), + new boost::posix_time::time_facet("%Y-%m-%d %H:%M:%S.%f-0000")) ); + ss << "expire " << ClockService::abstime(timeout_); + return ss.str(); +} + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "TimerEvent.mpp"