Скачиваний:
22
Добавлен:
01.05.2014
Размер:
3.74 Кб
Скачать
#ifndef TIMER_H
#define TIMER_H

#include <signal.h>
#include <time.h>
#include <errno.h>

typedef void (*SIGFUNC)(int, siginfo*, void*);

class timer
{
	timer_t           timer_id;
	int               status;
	struct itimerspec val;
    public:
	/* constructor: setup a timer */
	timer( int signo, SIGFUNC action, int timer_val, 
               clock_t sys_clock = CLOCK_REALTIME)
	{
		struct sigaction sigv;

		status = 0;

		sigemptyset( &sigv.sa_mask );
	        sigv.sa_flags = SA_SIGINFO;
       	 	sigv.sa_sigaction = action;
		if (sigaction( signo, &sigv, 0 ) == -1)
		{
			perror("sigaction");
			status = errno;
		}
		else
		{
			struct sigevent sigx; 

			sigx.sigev_notify   = SIGEV_SIGNAL;
	                sigx.sigev_signo    = signo;
       	         	sigx.sigev_value.sival_int = timer_val;

			if (timer_create( sys_clock, &sigx, &timer_id ) 
                                 == -1)
			{
				perror("timer_create");
				status = errno;
			}
		}
	};

	/* destructor: discard a timer */
	~timer()
	{
		if (status == 0)
		{
			stop();
		        if (timer_delete( timer_id ) == -1)
			{
			    perror( "timer_delete" );
			}
		}
	};

	/* Check timer status */
	int operator!()
	{
		return status ? 1 : 0;
	};

	/* setup a relative time timer */
	int run( long start_sec, long start_nsec, 
                 long reload_sec, long reload_nsec )
	{
		if (status) return -1;

		val.it_value.tv_sec     = start_sec;
                val.it_value.tv_nsec    = start_nsec;
                val.it_interval.tv_sec  = reload_sec;
                val.it_interval.tv_nsec = reload_nsec;

                if (timer_settime( timer_id, 0, &val, 0 ) == -1 )
                {
                        perror("timer_settime");
			status = errno;
                        return -1;
                }

		return 0;
	};

	/* setup an absolute time timer */
	int run( time_t start_time, long reload_sec, long reload_nsec )
	{
		if (status) return -1;

		val.it_value.tv_sec     = start_time;
                val.it_value.tv_nsec    = 0;
                val.it_interval.tv_sec  = reload_sec;
                val.it_interval.tv_nsec = reload_nsec;

                if (timer_settime( timer_id, TIMER_ABSTIME, &val, 
                                   0 ) == -1 )
                {
                        perror("timer_settime");
			status = errno;
                        return -1;
                }

		return 0;
	};

	/* Stop a timer from running */
	int stop()
	{
		if (status) return -1;

		val.it_value.tv_sec     = 0;
                val.it_value.tv_nsec    = 0;
                val.it_interval.tv_sec  = 0;
                val.it_interval.tv_nsec = 0;

                if (timer_settime( timer_id, 0, &val, 0 ) == -1 )
                {
                        perror("timer_settime");
			status = errno;
                        return -1;
                }

		return 0;
	};

	/* Get timer overrun statistic */
	int  overrun()
	{
		if (status) return -1;
		
		return timer_getoverrun( timer_id ); 
	};

	/* Get timer remaining time to expiration */
	int values( long& sec, long& nsec )
	{
		if (status) return -1;

		if (timer_gettime( timer_id, &val ) == -1)
		{
			perror(" timer_gettime" );
			status = errno;
			return -1;
		}

		sec  = val.it_value.tv_sec;
		nsec = val.it_value.tv_nsec;
		return 0;
	};

	/* Overload << operator for timer objects */
	friend ostream& operator<<( ostream& os, timer& obj)
	{
		long sec, nsec;
		obj.values( sec, nsec );

		double tval = sec + ((double)nsec/1000000000.0);
		os << " time left: " << tval ;
		return os;
	};
};


#endif


		
Соседние файлы в папке ch9