timer_poll.h
/* * File: timer_poll.h * Author: Administrator */
#ifndef TIMER_POLL_H #define TIMER_POLL_H #include <sys/types.h> #include <fcntl.h> #include <signal.h> #include <sys/epoll.h> #include <stdlib.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <sys/time.h> #include <sys/resource.h> #include <sys/timerfd.h> #include <unistd.h> #include <pthread.h> #include <map>
#define MAXFDS 128 #define EVENTS 100 class timer; typedef int(*timer_callback)(timer &);//user callback
class timer { public:
timer() : timer_internal(0.0), cb(0), timer_id(0), repeat(0), userdata(0){} timer(double internal_value, int (*callback)(timer &ptimer), void *data, int rep) : timer_internal(internal_value), cb(callback), userdata(data), repeat(rep) { timer_id = timerfd_create(CLOCK_REALTIME, 0); setNonBlock(timer_id); }
timer(const timer &ptimer); timer & operator=(const timer &ptimer); int timer_start(); int timer_stop(); int timer_modify_internal(double timer_internal);
int timer_get_id() { return timer_id; }
void *timer_get_userdata() { return userdata; }
timer_callback get_user_callback() { return cb; }
~timer() { timer_stop(); }
private:
bool setNonBlock (int fd) { int flags = fcntl (fd, F_GETFL, 0); flags |= O_NONBLOCK; if (-1 == fcntl (fd, F_SETFL, flags)) { return false; } return true; } int timer_id; double timer_internal; void *userdata; bool repeat;//will the timer repeat or only once timer_callback cb; } ; class timers_poll { public: timers_poll(int max_num=128) { active = 1; epfd = epoll_create(max_num); }
int timers_poll_add_timer(timer &ptimer); int timers_poll_del_timer(timer &ptimer); int run();
int timers_poll_deactive() { active = 0; }
~ timers_poll() {
} private: int epfd; int active; std::map<int, timer> timers_map; /* data */ } ; #endif /* TIMER_POLL_H */
timer_poll.cpp
/* * File: timer_poll.cpp * Author: Administrator */
#include <cstdlib> #include "timer_poll.h"
using namespace std;
timer::timer(const timer& ptimer) { timer_internal = ptimer.timer_internal; cb = ptimer.cb; timer_id = ptimer.timer_id; repeat = ptimer.repeat; userdata = ptimer.userdata; }
timer & timer::operator =(const timer& ptimer) { if (this == &ptimer) { return *this; }
timer_internal = ptimer.timer_internal; cb = ptimer.cb; timer_id = ptimer.timer_id; repeat = ptimer.repeat; userdata = ptimer.userdata; return *this; }
int timer::timer_start() { struct itimerspec ptime_internal = {0}; ptime_internal.it_value.tv_sec = (int) timer_internal; ptime_internal.it_value.tv_nsec = (timer_internal - (int) timer_internal)*1000000; if(repeat) { ptime_internal.it_interval.tv_sec = ptime_internal.it_value.tv_sec; ptime_internal.it_interval.tv_nsec = ptime_internal.it_value.tv_nsec; }
timerfd_settime(timer_id, 0, &ptime_internal, NULL); return 0; }
int timer::timer_stop() { close(timer_id); return 0; }
int timer::timer_modify_internal(double timer_internal) { this->timer_internal = timer_internal; timer_start(); }
int timers_poll::timers_poll_add_timer(timer& ptimer) { int timer_id = ptimer.timer_get_id(); struct epoll_event ev; ev.data.fd = timer_id; ev.events = EPOLLIN | EPOLLET; timers_map[timer_id] = ptimer; //add or modify epoll_ctl (epfd, EPOLL_CTL_ADD, timer_id, &ev); ptimer.timer_start();
return 0; }
int timers_poll::timers_poll_del_timer(timer& ptimer) { int timer_id = ptimer.timer_get_id(); struct epoll_event ev; ev.data.fd = timer_id; ev.events = EPOLLIN | EPOLLET; epoll_ctl (epfd, EPOLL_CTL_DEL, timer_id, &ev); timers_map.erase(timer_id);
return 0; }
int timers_poll::run() { char buf[128] ={0}; for (; active ; ) { struct epoll_event events[MAXFDS] ={0}; int nfds = epoll_wait (epfd, events, MAXFDS, -1); for (int i = 0; i < nfds; ++i) { std::map<int, timer>::iterator itmp = timers_map.find(events[i].data.fd); if (itmp != timers_map.end()) { //timer ptimer = itmp->second; while (read(events[i].data.fd, buf, 128) > 0); itmp->second.get_user_callback()(itmp->second); } } } }
main.cpp
/* * File: main.cpp * Author: Administrator */
#include <cstdlib> #include <iostream>
#include "timer_poll.h"
using namespace std;
int callback(timer &ptimer) { printf("timer id=%d:%s\n", ptimer.timer_get_id(), (char *) ptimer.timer_get_userdata()); return 0; }
void *thread_fun(void *data) { timers_poll *my_timers = (timers_poll *)data; my_timers->run(); }
/* * */ int main(int argc, char** argv) { timers_poll my_timers(128); pthread_t thread_id = 0; pthread_create(&thread_id, NULL, thread_fun, &my_timers);
timer timer1(1.05, callback, (void *) "hello 1",0); timer timer2(1.10, callback, (void *) "hello 2",0);
// timer1.timer_start(); // timer2.timer_start();
my_timers.timers_poll_add_timer(timer1); my_timers.timers_poll_add_timer(timer2);
sleep(5); my_timers.timers_poll_del_timer(timer2); cout<<"del complete"<<endl; timer1.timer_modify_internal(5.1); //timer2.timer_modify_internal(10.1); cout<<"modify complete"<<endl; sleep(4); //my_timers.timers_poll_del_timer(timer2);
//sleep(5);
//my_timers.timers_poll_deactive();
pthread_join(thread_id,NULL); return 0; }
|
请发表评论