// Copyright (c) 2004 David Muse
// See the COPYING file for more information
#include <rudiments/private/config.h>
#include <rudiments/intervaltimer.h>
#include <rudiments/rawbuffer.h>
#include <rudiments/error.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef RUDIMENTS_NAMESPACE
namespace rudiments {
#endif
class intervaltimerprivate {
friend class intervaltimer;
public:
int _which;
itimerval _values;
};
intervaltimer::intervaltimer(int which) {
pvt=new intervaltimerprivate;
pvt->_which=which;
initialize();
}
intervaltimer::~intervaltimer() {
delete pvt;
}
void intervaltimer::initialize() {
rawbuffer::zero(&pvt->_values,sizeof(pvt->_values));
}
void intervaltimer::setInitialInterval(long seconds, long microseconds) {
pvt->_values.it_value.tv_sec=seconds;
pvt->_values.it_value.tv_usec=microseconds;
}
void intervaltimer::setInitialInterval(const timeval *tv) {
pvt->_values.it_value=*tv;
}
void intervaltimer::setPeriodicInterval(long seconds, long microseconds) {
pvt->_values.it_interval.tv_sec=seconds;
pvt->_values.it_interval.tv_usec=microseconds;
}
void intervaltimer::setPeriodicInterval(const timeval *tv) {
pvt->_values.it_interval=*tv;
}
void intervaltimer::setIntervals(long seconds, long microseconds) {
setInitialInterval(seconds,microseconds);
setPeriodicInterval(seconds,microseconds);
}
void intervaltimer::setIntervals(const timeval *tv) {
setInitialInterval(tv);
setPeriodicInterval(tv);
}
void intervaltimer::setIntervals(const itimerval *itv) {
pvt->_values=*itv;
}
void intervaltimer::getInitialInterval(long *seconds,
long *microseconds) const {
if (seconds) {
*seconds=pvt->_values.it_value.tv_sec;
}
if (microseconds) {
*microseconds=pvt->_values.it_value.tv_usec;
}
}
void intervaltimer::getInitialInterval(timeval *tv) const {
*tv=pvt->_values.it_value;
}
void intervaltimer::getPeriodicInterval(long *seconds,
long *microseconds) const {
if (seconds) {
*seconds=pvt->_values.it_interval.tv_sec;
}
if (microseconds) {
*microseconds=pvt->_values.it_interval.tv_usec;
}
}
void intervaltimer::getPeriodicInterval(timeval *tv) const {
*tv=pvt->_values.it_interval;
}
void intervaltimer::getIntervals(itimerval *itv) const {
*itv=pvt->_values;
}
bool intervaltimer::start() const {
return start(NULL);
}
bool intervaltimer::start(itimerval *itv) const {
// Solaris 8 complains if the 2nd argument isn't cast
int result;
do {
result=setitimer(pvt->_which,
const_cast<itimerval *>(&pvt->_values),itv);
} while (result==-1 && error::getErrorNumber()==EINTR);
return !result;
}
bool intervaltimer::getTimeRemaining(long *seconds, long *microseconds) const {
itimerval val;
int result;
do {
result=getitimer(pvt->_which,&val);
} while (result==-1 && error::getErrorNumber()==EINTR);
if (seconds) {
*seconds=val.it_value.tv_sec;
}
if (microseconds) {
*microseconds=val.it_value.tv_usec;
}
return !result;
}
bool intervaltimer::getTimeRemaining(timeval *tv) const {
// Some systems define tv_sec and/or tv_usec as something other than
// long so we need to get longs and then let them auto-cast during
// assignment below.
long sec;
long usec;
bool retval=getTimeRemaining((long*)(&sec),&usec);
tv->tv_sec=sec;
tv->tv_usec=usec;
return retval;
}
bool intervaltimer::stop() const {
itimerval stopvals;
rawbuffer::zero(&stopvals,sizeof(stopvals));
return start(&stopvals);
}
#ifdef RUDIMENTS_NAMESPACE
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1