mirror of
https://github.com/wfjm/w11.git
synced 2026-02-06 16:55:09 +00:00
first practical version of RtimerFd
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
// $Id: RtimerFd.cpp 488 2013-02-16 18:49:47Z mueller $
|
||||
// $Id: RtimerFd.cpp 852 2017-02-18 12:43:31Z mueller $
|
||||
//
|
||||
// Copyright 2013- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
// Copyright 2013-2017 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// This program is free software; you may redistribute and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
@@ -13,12 +13,13 @@
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2013-01-11 473 1.0 Initial version
|
||||
// 2017-02-18 852 1.0 Initial version
|
||||
// 2013-01-11 473 0.1 First draft
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version $Id: RtimerFd.cpp 488 2013-02-16 18:49:47Z mueller $
|
||||
\version $Id: RtimerFd.cpp 852 2017-02-18 12:43:31Z mueller $
|
||||
\brief Implemenation of class RtimerFd.
|
||||
*/
|
||||
|
||||
@@ -44,37 +45,109 @@ namespace Retro {
|
||||
//! FIXME_docs
|
||||
|
||||
RtimerFd::RtimerFd()
|
||||
{
|
||||
fFd = timerfd_create(CLOCK_MONOTONIC,0); // use MONOTONIC; no flags
|
||||
if (fFd < 0)
|
||||
throw Rexception("RtimerFd::<ctor>", "timerfd() failed: ", errno);
|
||||
}
|
||||
: fFd(-1)
|
||||
{}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
RtimerFd::~RtimerFd()
|
||||
{
|
||||
close(fFd);
|
||||
Close();
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RtimerFd::SetRelTimer(boost::posix_time::time_duration interval,
|
||||
boost::posix_time::time_duration initial)
|
||||
void RtimerFd::Open(clockid_t clkid)
|
||||
{
|
||||
itimerspec its;
|
||||
itimerspec old;
|
||||
long sf = 1000000000/interval.ticks_per_second();
|
||||
its.it_interval.tv_sec = interval.total_seconds();
|
||||
its.it_interval.tv_nsec = interval.fractional_seconds() * sf;
|
||||
its.it_value.tv_sec = initial.total_seconds();
|
||||
its.it_value.tv_nsec = initial.fractional_seconds() * sf;
|
||||
int irc = timerfd_settime(fFd, 0, &its, &old);
|
||||
if (irc < 0)
|
||||
throw Rexception("RtimerFd::SetRelTimer()", "timerfd() failed: ", errno);
|
||||
if (IsOpen())
|
||||
throw Rexception("RtimerFd::Open()", "bad state: already open");
|
||||
|
||||
fFd = ::timerfd_create(clkid, TFD_NONBLOCK);
|
||||
if (!IsOpen())
|
||||
throw Rexception("RtimerFd::Open()", "timerfd_create() failed: ", errno);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RtimerFd::Close()
|
||||
{
|
||||
if (IsOpen()) {
|
||||
::close(fFd);
|
||||
fFd = -1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RtimerFd::SetRelative(const Rtime& dt)
|
||||
{
|
||||
if (!IsOpen())
|
||||
throw Rexception("RtimerFd::SetRelative()", "bad state: not open");
|
||||
|
||||
if (dt.Sec() <= 0 || dt.NSec() <= 0)
|
||||
throw Rexception("RtimerFd::SetRelative()",
|
||||
"bad value: dt zero or negative ");
|
||||
|
||||
struct itimerspec itspec;
|
||||
itspec.it_interval.tv_sec = 0;
|
||||
itspec.it_interval.tv_nsec = 0;
|
||||
itspec.it_value = dt.Timespec();
|
||||
|
||||
if (::timerfd_settime(fFd, 0, &itspec, nullptr) < 0)
|
||||
throw Rexception("RtimerFd::SetRelative()",
|
||||
"timerfd_settime() failed: ", errno);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
void RtimerFd::Cancel()
|
||||
{
|
||||
if (!IsOpen())
|
||||
throw Rexception("RtimerFd::Cancel()", "bad state: not open");
|
||||
|
||||
struct itimerspec itspec;
|
||||
itspec.it_interval.tv_sec = 0;
|
||||
itspec.it_interval.tv_nsec = 0;
|
||||
itspec.it_value.tv_sec = 0;
|
||||
itspec.it_value.tv_nsec = 0;
|
||||
|
||||
// cancel running timers
|
||||
if (::timerfd_settime(fFd, 0, &itspec, nullptr) < 0)
|
||||
throw Rexception("RtimerFd::Cancel()",
|
||||
"timerfd_settime() failed: ", errno);
|
||||
|
||||
// clear aready experied timers
|
||||
uint64_t cnt;
|
||||
int irc = ::read(fFd, &cnt, sizeof(cnt));
|
||||
if (irc < 0 && errno != EAGAIN)
|
||||
throw Rexception("RtimerFd::Cancel()", "read() failed: ", errno);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
uint64_t RtimerFd::Read()
|
||||
{
|
||||
if (!IsOpen())
|
||||
throw Rexception("RtimerFd::Read()", "bad state: not open");
|
||||
|
||||
uint64_t cnt;
|
||||
int irc = ::read(fFd, &cnt, sizeof(cnt));
|
||||
if (irc < 0) {
|
||||
if (errno == EAGAIN) return 0;
|
||||
throw Rexception("RtimerFd::Read()", "read() failed: ", errno);
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
Reference in New Issue
Block a user