diff --git a/source/mt_timer.c b/source/mt_timer.c index c01f18b..65384d8 100644 --- a/source/mt_timer.c +++ b/source/mt_timer.c @@ -27,23 +27,54 @@ #include #include #include +#include +#include #include "mt_timer.h" int timer_init(MT_TIMER_OBJECT *object, void *(*thread_handler)(void *arg), int max_num) { + struct epoll_event event; + assert(NULL != object); + if(true == object->timer_active_flag) + return 0; + + object->timer_event_fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); + if(-1 == object->timer_event_fd) + { + MT_TIMER_PRINT_INL("MT-Timer error: eventfd() failed, %s!\n", strerror(errno)); + return -1; + } object->timer_max = max_num; object->timer_active_flag = true; object->timer_epoll_fd = epoll_create(max_num); if(object->timer_epoll_fd < 0) { MT_TIMER_PRINT_INL("MT-Timer error: epoll_create failed %s.\n", strerror(errno)); + close(object->timer_event_fd); + object->timer_event_fd = -1; return -1; } - + + event.data.ptr = NULL; + event.events = EPOLLIN | EPOLLET; + if(epoll_ctl(object->timer_epoll_fd, EPOLL_CTL_ADD, object->timer_event_fd, &event) < 0) + { + fprintf(stderr, "epoll: epoll_ctl ADD failed, %s\n", strerror(errno)); + close(object->timer_epoll_fd); + close(object->timer_event_fd); + object->timer_epoll_fd = -1; + object->timer_event_fd = -1; + return -1; + } + if(pthread_create(&object->timer_thread_id, NULL, thread_handler, NULL) != 0) { MT_TIMER_PRINT_INL("MT-Timer error: pthread_create failed %s.\n", strerror(errno)); + close(object->timer_epoll_fd); + close(object->timer_event_fd); + object->timer_epoll_fd = -1; + object->timer_event_fd = -1; return -1; } @@ -52,28 +83,28 @@ int timer_init(MT_TIMER_OBJECT *object, void *(*thread_handler)(void *arg), int void timer_deinit(MT_TIMER_OBJECT *object) { - struct itimerspec itimespec; - + uint64_t quit = 0x51; + assert(NULL != object); + if(false == object->timer_active_flag) + return ; object->timer_active_flag = false; - - itimespec.it_value.tv_sec = 0; - itimespec.it_value.tv_nsec = 50; - itimespec.it_interval.tv_sec = 0; - itimespec.it_interval.tv_nsec = 0; - - timer_add(object, &itimespec, 0, NULL, NULL, NULL); + usleep(100); + write(object->timer_event_fd, &quit, sizeof(uint64_t)); /* wakeup thread */ pthread_join(object->timer_thread_id, NULL); timer_clear(object); close(object->timer_epoll_fd); + close(object->timer_event_fd); object->timer_epoll_fd = -1; + object->timer_event_fd = -1; } int timer_add(MT_TIMER_OBJECT *object, struct itimerspec *itimespec, int repeat, timer_callback_t cb, void *data, timer_release_t rb) { + uint64_t quit = 0x51; struct epoll_event event; MT_TIMER_NODE *handler = NULL; - + assert(NULL != object); handler = (MT_TIMER_NODE *)malloc(sizeof(MT_TIMER_NODE)); if(NULL == handler) { @@ -109,7 +140,7 @@ int timer_add(MT_TIMER_OBJECT *object, struct itimerspec *itimespec, free(handler); return -4; } - + write(object->timer_event_fd, &quit, sizeof(uint64_t)); /* wakeup thread */ pthread_rwlock_wrlock(&object->timer_rwlock); HASH_ADD_INT(object->timer_head, timer_fd, handler); pthread_rwlock_unlock(&object->timer_rwlock); @@ -121,7 +152,7 @@ int timer_del(MT_TIMER_OBJECT *object, int timerfd) { struct epoll_event event; MT_TIMER_NODE *handler = NULL; - + assert(NULL != object); pthread_rwlock_rdlock(&object->timer_rwlock); HASH_FIND_INT(object->timer_head, &timerfd, handler); pthread_rwlock_unlock(&object->timer_rwlock); @@ -149,6 +180,7 @@ int timer_del(MT_TIMER_OBJECT *object, int timerfd) int timer_count(MT_TIMER_OBJECT *object) { + assert(NULL != object); return HASH_COUNT(object->timer_head); } @@ -156,7 +188,7 @@ int timer_clear(MT_TIMER_OBJECT *object) { struct epoll_event event; MT_TIMER_NODE *handler = NULL; - + assert(NULL != object); event.events = EPOLLIN | EPOLLET; for(handler = object->timer_head; handler != NULL; handler = handler->hh.next) { diff --git a/source/mt_timer.h b/source/mt_timer.h index 0de8dd1..4b079b7 100644 --- a/source/mt_timer.h +++ b/source/mt_timer.h @@ -85,6 +85,7 @@ typedef struct { typedef struct { int timer_max; int timer_epoll_fd; + int timer_event_fd; bool timer_active_flag; MT_TIMER_NODE *timer_head; pthread_t timer_thread_id; @@ -95,6 +96,7 @@ typedef struct { static void *mt_timer_thread_##name(void *arg) \ { \ int nfds, i; \ + uint64_t u64; \ char buf[128]; \ struct epoll_event event; \ MT_TIMER_NODE *timer_node = NULL; \ @@ -111,7 +113,10 @@ typedef struct { { \ timer_node = (MT_TIMER_NODE *)events[i].data.ptr; \ if(NULL == timer_node) \ + { \ + read(mt_timer_##name.timer_event_fd, &u64, sizeof(uint64_t)); \ continue; \ + } \ while(read(timer_node->timer_fd, buf, sizeof(buf)) > 0); \ if(NULL == timer_node->timer_cb) \ continue; \ @@ -153,7 +158,7 @@ extern int timer_clear(MT_TIMER_OBJECT *object); /************************** API Interface **************************/ #define TIMER_CREATE(name) \ - MT_TIMER_OBJECT mt_timer_##name = {0, -1, false, NULL, 0, PTHREAD_RWLOCK_INITIALIZER}; \ + MT_TIMER_OBJECT mt_timer_##name = {0, -1, -1, false, NULL, 0, PTHREAD_RWLOCK_INITIALIZER}; \ TIMER_THREAD_CREATE(name) #define TIMER_DECLEAR(name) \ extern MT_TIMER_OBJECT mt_timer_##name