implementation multiple timer
1.change name from timer.c/h to mt_timer.c/h 2.move thread and variable to mt_timer.h Signed-off-by: qiyin.zhang <qiyin.zhang@ihuisen.com>master
parent
75990f0447
commit
2b11efe1f9
4
Makefile
4
Makefile
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
all: timer.c test.c
|
||||
gcc test.c timer.c -pthread -o timer -Wall
|
||||
all: mt_timer.c test.c
|
||||
gcc test.c mt_timer.c -pthread -o timer -Wall
|
||||
|
||||
clean:
|
||||
rm timer
|
||||
|
|
|
|||
|
|
@ -0,0 +1,146 @@
|
|||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mt_timer.h"
|
||||
|
||||
int timer_init(MT_TIMER_OBJECT *object, void *(*thread_handler)(void *arg), int max_num)
|
||||
{
|
||||
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));
|
||||
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));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void timer_deinit(MT_TIMER_OBJECT *object)
|
||||
{
|
||||
struct itimerspec itimespec;
|
||||
|
||||
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);
|
||||
pthread_join(object->timer_thread_id, NULL);
|
||||
timer_clear(object);
|
||||
}
|
||||
|
||||
int timer_add(MT_TIMER_OBJECT *object, struct itimerspec *itimespec,
|
||||
int repeat, timer_callback_t cb, void *data)
|
||||
{
|
||||
struct epoll_event event;
|
||||
MT_TIMER_NODE *handler = NULL;
|
||||
|
||||
handler = (MT_TIMER_NODE *)malloc(sizeof(MT_TIMER_NODE));
|
||||
if(NULL == handler)
|
||||
{
|
||||
MT_TIMER_PRINT_INL("MT-Timer error: malloc failed %s.\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
handler->timer_cb = cb;
|
||||
handler->timer_cnt = repeat;
|
||||
handler->timer_data = data;
|
||||
handler->timer_fd = timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC|TFD_NONBLOCK);
|
||||
if(handler->timer_fd < 0)
|
||||
{
|
||||
MT_TIMER_PRINT_INL("MT-Timer error: timerfd_create failed %s.\n", strerror(errno));
|
||||
free(handler);
|
||||
return -2;
|
||||
}
|
||||
if(timerfd_settime(handler->timer_fd, 0, itimespec, NULL) == -1)
|
||||
{
|
||||
MT_TIMER_PRINT_INL("MT-Timer error: timerfd_settime failed %s.\n", strerror(errno));
|
||||
close(handler->timer_fd);
|
||||
free(handler);
|
||||
return -3;
|
||||
}
|
||||
|
||||
event.events = EPOLLIN | EPOLLET;
|
||||
event.data.ptr = handler;
|
||||
if(epoll_ctl(object->timer_epoll_fd, EPOLL_CTL_ADD, handler->timer_fd, &event) < 0)
|
||||
{
|
||||
MT_TIMER_PRINT_INL("MT-Timer error: epoll_ctl ADD failed %s.\n", strerror(errno));
|
||||
close(handler->timer_fd);
|
||||
free(handler);
|
||||
return -4;
|
||||
}
|
||||
|
||||
pthread_rwlock_wrlock(&object->timer_rwlock);
|
||||
HASH_ADD_INT(object->timer_head, timer_fd, handler);
|
||||
pthread_rwlock_unlock(&object->timer_rwlock);
|
||||
|
||||
return handler->timer_fd;
|
||||
}
|
||||
|
||||
int timer_del(MT_TIMER_OBJECT *object, int timerfd)
|
||||
{
|
||||
struct epoll_event event;
|
||||
MT_TIMER_NODE *handler = NULL;
|
||||
|
||||
HASH_FIND_INT(object->timer_head, &timerfd, handler);
|
||||
if(NULL == handler)
|
||||
return 0;
|
||||
|
||||
event.data.ptr = (void *)handler;
|
||||
event.events = EPOLLIN | EPOLLET;
|
||||
if(epoll_ctl(object->timer_epoll_fd, EPOLL_CTL_DEL, handler->timer_fd, &event) < 0)
|
||||
{
|
||||
MT_TIMER_PRINT_INL("MT-Timer error: epoll_ctl DEL failed %s.\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_rwlock_wrlock(&object->timer_rwlock);
|
||||
HASH_DEL(object->timer_head, handler);
|
||||
pthread_rwlock_unlock(&object->timer_rwlock);
|
||||
close(handler->timer_fd);
|
||||
free(handler);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int timer_count(MT_TIMER_OBJECT *object)
|
||||
{
|
||||
return HASH_COUNT(object->timer_head);
|
||||
}
|
||||
|
||||
int timer_clear(MT_TIMER_OBJECT *object)
|
||||
{
|
||||
struct epoll_event event;
|
||||
MT_TIMER_NODE *handler = NULL;
|
||||
|
||||
event.events = EPOLLIN | EPOLLET;
|
||||
for(handler = object->timer_head; handler != NULL; handler = handler->hh.next)
|
||||
{
|
||||
event.data.ptr = (void *)handler;
|
||||
if(epoll_ctl(object->timer_epoll_fd, EPOLL_CTL_DEL, handler->timer_fd, &event) < 0)
|
||||
{
|
||||
MT_TIMER_PRINT_INL("MT-Timer error: epoll_ctl CLEAR failed %s.\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
pthread_rwlock_wrlock(&object->timer_rwlock);
|
||||
HASH_DEL(object->timer_head, handler);
|
||||
pthread_rwlock_unlock(&object->timer_rwlock);
|
||||
close(handler->timer_fd);
|
||||
free(handler);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2019 极简美 @ konishi5202@163.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _MT_TIMER_H__
|
||||
#define _MT_TIMER_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <pthread.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/timerfd.h>
|
||||
#include "uthash.h"
|
||||
|
||||
#define DEBUG_ENABLE
|
||||
/************************** Debug Config Start **************************/
|
||||
#ifdef DEBUG_ENABLE
|
||||
|
||||
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
|
||||
|
||||
#ifdef EFSM_PRINT
|
||||
#define MT_TIMER_PRINT_INL(...) EFSM_PRINT(__VA_ARGS__)
|
||||
#else
|
||||
#define MT_TIMER_PRINT_INL(...) printf(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#ifdef EFSM_PRINT
|
||||
#define MT_TIMER_PRINT_INL(format, args...) EFSM_PRINT(format, ##args)
|
||||
#else
|
||||
#define MT_TIMER_PRINT_INL(format, args...) printf(format, ##args)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
|
||||
#define MT_TIMER_PRINT_INL(...)
|
||||
#else
|
||||
#define MT_TIMER_PRINT_INL(format, args...)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/************************** Debug Config End **************************/
|
||||
|
||||
#ifndef bool
|
||||
typedef enum{false, true} bool;
|
||||
#define bool bool
|
||||
#endif
|
||||
|
||||
typedef void (*timer_callback_t)(void *data);
|
||||
|
||||
typedef struct {
|
||||
int timer_fd;
|
||||
int timer_cnt;
|
||||
void *timer_data;
|
||||
UT_hash_handle hh;
|
||||
timer_callback_t timer_cb;
|
||||
}MT_TIMER_NODE; /* MT mean multiple */
|
||||
|
||||
typedef struct {
|
||||
int timer_max;
|
||||
int timer_epoll_fd;
|
||||
bool timer_active_flag;
|
||||
MT_TIMER_NODE *timer_head;
|
||||
pthread_t timer_thread_id;
|
||||
pthread_rwlock_t timer_rwlock;
|
||||
}MT_TIMER_OBJECT;
|
||||
|
||||
#define TIMER_THREAD_CREATE(name) \
|
||||
static void *mt_timer_thread_##name(void *arg) \
|
||||
{ \
|
||||
int nfds, i; \
|
||||
char buf[128]; \
|
||||
MT_TIMER_NODE *timer_node = NULL; \
|
||||
struct epoll_event events[mt_timer_##name.timer_max]; \
|
||||
/*pthread_detach(pthread_self());*/ \
|
||||
MT_TIMER_PRINT_INL("MT-Timer Info: %s thread is running.\n", #name); \
|
||||
while(mt_timer_##name.timer_active_flag) \
|
||||
{ \
|
||||
nfds = epoll_wait(mt_timer_##name.timer_epoll_fd, events, mt_timer_##name.timer_max, -1); \
|
||||
if(nfds <= 0) \
|
||||
continue; \
|
||||
for(i = 0; i < nfds; i++) \
|
||||
{ \
|
||||
timer_node = (MT_TIMER_NODE *)events[i].data.ptr; \
|
||||
if(NULL == timer_node) \
|
||||
continue; \
|
||||
while(read(timer_node->timer_fd, buf, sizeof(buf)) > 0); \
|
||||
if(NULL == timer_node->timer_cb) \
|
||||
continue; \
|
||||
if(-1 == timer_node->timer_cnt) \
|
||||
timer_node->timer_cb(timer_node->timer_data); \
|
||||
else \
|
||||
{ \
|
||||
if(timer_node->timer_cnt) \
|
||||
{ \
|
||||
timer_node->timer_cb(timer_node->timer_data); \
|
||||
timer_node->timer_cnt--; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
MT_TIMER_PRINT_INL("MT-Timer Info: %s thread is exit.\n", #name); \
|
||||
pthread_exit(NULL); \
|
||||
}
|
||||
|
||||
extern int timer_init(MT_TIMER_OBJECT *object, void *(*thread_handler)(void *arg), int max_num);
|
||||
extern void timer_deinit(MT_TIMER_OBJECT *object);
|
||||
extern int timer_add(MT_TIMER_OBJECT *object, struct itimerspec *itimespec,
|
||||
int repeat, timer_callback_t cb, void *data);
|
||||
extern int timer_del(MT_TIMER_OBJECT *object, int timerfd);
|
||||
extern int timer_count(MT_TIMER_OBJECT *object);
|
||||
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}; \
|
||||
TIMER_THREAD_CREATE(name)
|
||||
#define TIMER_DECLEAR(name) \
|
||||
extern MT_TIMER_OBJECT mt_timer_##name
|
||||
#define TIMER_INIT(name, max) \
|
||||
timer_init(&mt_timer_##name, mt_timer_thread_##name, max)
|
||||
#define TIMER_DEINIT(name) \
|
||||
timer_deinit(&mt_timer_##name)
|
||||
#define TIMER_ADD(name, itimespec, repeat, cb, data) \
|
||||
timer_add(&mt_timer_##name, itimespec, repeat, cb, data)
|
||||
#define TIMER_DEL(name, timerfd) \
|
||||
timer_del(&mt_timer_##name, timerfd)
|
||||
#define TIMER_COUNT(name) timer_count(&mt_timer_##name)
|
||||
#define TIMER_CLEAR(name) timer_clear(&mt_timer_##name)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _MT_TIMER_H__
|
||||
|
||||
24
test.c
24
test.c
|
|
@ -2,7 +2,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "timer.h"
|
||||
#include "mt_timer.h"
|
||||
|
||||
void timeout_handle(void *arg)
|
||||
{
|
||||
|
|
@ -14,29 +14,31 @@ void timeout_handler(void *arg)
|
|||
printf("[%ld]:timeout2\n", time(NULL));
|
||||
}
|
||||
|
||||
TIMER_CREATE(test);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int timer1;
|
||||
int timer;
|
||||
struct itimerspec itimespec;
|
||||
|
||||
timer_init(10);
|
||||
TIMER_INIT(test, 10);
|
||||
itimespec.it_value.tv_sec = 3;
|
||||
itimespec.it_value.tv_nsec = 0;
|
||||
itimespec.it_interval.tv_sec = 1;
|
||||
itimespec.it_interval.tv_nsec = 0;
|
||||
|
||||
timer1 = timer_add(&itimespec, 8, timeout_handle, NULL);
|
||||
timer_add(&itimespec, 3, timeout_handler, NULL);
|
||||
printf("[%ld]:timer_add : %d\n", time(NULL), timer_count());
|
||||
timer = TIMER_ADD(test, &itimespec, 8, timeout_handle, NULL);
|
||||
TIMER_ADD(test, &itimespec, 3, timeout_handler, NULL);
|
||||
printf("[%ld]:timer_add : %d\n", time(NULL), TIMER_COUNT(test));
|
||||
|
||||
sleep(4);//getchar();
|
||||
timer_del(timer1);
|
||||
printf("[%ld]:timer_del : %d\n", time(NULL), timer_count());
|
||||
timer_clear();
|
||||
printf("[%ld]:timer_clear : %d\n", time(NULL), timer_count());
|
||||
TIMER_DEL(test, timer);
|
||||
printf("[%ld]:timer_del : %d\n", time(NULL), TIMER_COUNT(test));
|
||||
TIMER_CLEAR(test);
|
||||
printf("[%ld]:timer_clear : %d\n", time(NULL), TIMER_COUNT(test));
|
||||
getchar();
|
||||
|
||||
timer_deinit();
|
||||
TIMER_DEINIT(test);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
216
timer.c
216
timer.c
|
|
@ -1,216 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <sys/epoll.h>
|
||||
|
||||
#include "uthash.h"
|
||||
#include "timer.h"
|
||||
|
||||
#ifndef bool
|
||||
typedef enum{false, true} bool;
|
||||
#define bool bool
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int timer_fd;
|
||||
int timer_cnt;
|
||||
void *timer_data;
|
||||
UT_hash_handle hh;
|
||||
timer_callback_t timer_cb;
|
||||
}MT_TIMER_NODE;
|
||||
|
||||
typedef struct {
|
||||
int timer_max;
|
||||
int timer_epoll_fd;
|
||||
bool timer_active_flag;
|
||||
MT_TIMER_NODE *timer_head;
|
||||
pthread_t timer_thread_id;
|
||||
pthread_rwlock_t timer_rwlock;
|
||||
}MT_TIMER_OBJECT;
|
||||
|
||||
MT_TIMER_OBJECT timer_object_name = {0, -1, false, NULL, 0, PTHREAD_RWLOCK_INITIALIZER};
|
||||
|
||||
static void *mt_timer_thread_name(void *arg)
|
||||
{
|
||||
int nfds, i;
|
||||
char buf[128];
|
||||
MT_TIMER_NODE *timer_node = NULL;
|
||||
struct epoll_event events[timer_object_name.timer_max];
|
||||
|
||||
/*pthread_detach(pthread_self());*/
|
||||
printf("MT-Timer Info: timer thread is running.\n");
|
||||
while(timer_object_name.timer_active_flag)
|
||||
{
|
||||
nfds = epoll_wait(timer_object_name.timer_epoll_fd, events, timer_object_name.timer_max, -1);
|
||||
if(nfds <= 0)
|
||||
continue;
|
||||
for(i = 0; i < nfds; i++)
|
||||
{
|
||||
timer_node = (MT_TIMER_NODE *)events[i].data.ptr;
|
||||
if(NULL == timer_node)
|
||||
continue;
|
||||
while(read(timer_node->timer_fd, buf, sizeof(buf)) > 0);
|
||||
if(NULL == timer_node->timer_cb)
|
||||
continue;
|
||||
|
||||
if(-1 == timer_node->timer_cnt)
|
||||
timer_node->timer_cb(timer_node->timer_data);
|
||||
else
|
||||
{
|
||||
if(timer_node->timer_cnt)
|
||||
{
|
||||
timer_node->timer_cb(timer_node->timer_data);
|
||||
timer_node->timer_cnt--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("MT-Timer Info: timer thread is exit.\n");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
int timer_init(int max_num)
|
||||
{
|
||||
timer_object_name.timer_max = max_num;
|
||||
timer_object_name.timer_active_flag = true;
|
||||
timer_object_name.timer_epoll_fd = epoll_create(max_num);
|
||||
if(timer_object_name.timer_epoll_fd < 0)
|
||||
{
|
||||
printf("MT-Timer error: epoll_create failed %s.\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(pthread_create(&timer_object_name.timer_thread_id, NULL, mt_timer_thread_name, NULL) != 0)
|
||||
{
|
||||
printf("MT-Timer error: pthread_create failed %s.\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void timer_deinit(void)
|
||||
{
|
||||
struct itimerspec itimespec;
|
||||
|
||||
timer_object_name.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(&itimespec, 0, NULL, NULL);
|
||||
pthread_join(timer_object_name.timer_thread_id, NULL);
|
||||
timer_clear();
|
||||
}
|
||||
|
||||
int timer_add(struct itimerspec *itimespec, int repeat, timer_callback_t cb, void *data)
|
||||
{
|
||||
struct epoll_event event;
|
||||
MT_TIMER_NODE *handler = NULL;
|
||||
|
||||
handler = (MT_TIMER_NODE *)malloc(sizeof(MT_TIMER_NODE));
|
||||
if(NULL == handler)
|
||||
{
|
||||
printf("MT-Timer error: malloc failed %s.\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
handler->timer_cb = cb;
|
||||
handler->timer_cnt = repeat;
|
||||
handler->timer_data = data;
|
||||
handler->timer_fd = timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC|TFD_NONBLOCK);
|
||||
if(handler->timer_fd < 0)
|
||||
{
|
||||
printf("MT-Timer error: timerfd_create failed %s.\n", strerror(errno));
|
||||
free(handler);
|
||||
return -2;
|
||||
}
|
||||
if(timerfd_settime(handler->timer_fd, 0, itimespec, NULL) == -1)
|
||||
{
|
||||
printf("MT-Timer error: timerfd_settime failed %s.\n", strerror(errno));
|
||||
close(handler->timer_fd);
|
||||
free(handler);
|
||||
return -3;
|
||||
}
|
||||
|
||||
event.events = EPOLLIN | EPOLLET;
|
||||
event.data.ptr = handler;
|
||||
if(epoll_ctl(timer_object_name.timer_epoll_fd, EPOLL_CTL_ADD, handler->timer_fd, &event) < 0)
|
||||
{
|
||||
printf("MT-Timer error: epoll_ctl ADD failed %s.\n", strerror(errno));
|
||||
close(handler->timer_fd);
|
||||
free(handler);
|
||||
return -4;
|
||||
}
|
||||
|
||||
pthread_rwlock_wrlock(&timer_object_name.timer_rwlock);
|
||||
HASH_ADD_INT(timer_object_name.timer_head, timer_fd, handler);
|
||||
pthread_rwlock_unlock(&timer_object_name.timer_rwlock);
|
||||
|
||||
return handler->timer_fd;
|
||||
}
|
||||
|
||||
int timer_del(int timerfd)
|
||||
{
|
||||
struct epoll_event event;
|
||||
MT_TIMER_NODE *handler = NULL;
|
||||
|
||||
HASH_FIND_INT(timer_object_name.timer_head, &timerfd, handler);
|
||||
if(NULL == handler)
|
||||
return 0;
|
||||
|
||||
event.data.ptr = (void *)handler;
|
||||
event.events = EPOLLIN | EPOLLET;
|
||||
if(epoll_ctl(timer_object_name.timer_epoll_fd, EPOLL_CTL_DEL, handler->timer_fd, &event) < 0)
|
||||
{
|
||||
printf("MT-Timer error: epoll_ctl DEL failed %s.\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_rwlock_wrlock(&timer_object_name.timer_rwlock);
|
||||
HASH_DEL(timer_object_name.timer_head, handler);
|
||||
pthread_rwlock_unlock(&timer_object_name.timer_rwlock);
|
||||
close(handler->timer_fd);
|
||||
free(handler);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int timer_count(void)
|
||||
{
|
||||
int count = 0;
|
||||
pthread_rwlock_rdlock(&timer_object_name.timer_rwlock);
|
||||
count = (int) HASH_COUNT(timer_object_name.timer_head);
|
||||
pthread_rwlock_unlock(&timer_object_name.timer_rwlock);
|
||||
return count;
|
||||
}
|
||||
|
||||
int timer_clear(void)
|
||||
{
|
||||
struct epoll_event event;
|
||||
MT_TIMER_NODE *handler = NULL;
|
||||
|
||||
event.events = EPOLLIN | EPOLLET;
|
||||
for(handler = timer_object_name.timer_head; handler != NULL; handler = handler->hh.next)
|
||||
{
|
||||
event.data.ptr = (void *)handler;
|
||||
if(epoll_ctl(timer_object_name.timer_epoll_fd, EPOLL_CTL_DEL, handler->timer_fd, &event) < 0)
|
||||
{
|
||||
printf("MT-Timer error: epoll_ctl CLEAR failed %s.\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
pthread_rwlock_wrlock(&timer_object_name.timer_rwlock);
|
||||
HASH_DEL(timer_object_name.timer_head, handler);
|
||||
pthread_rwlock_unlock(&timer_object_name.timer_rwlock);
|
||||
close(handler->timer_fd);
|
||||
free(handler);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
23
timer.h
23
timer.h
|
|
@ -1,23 +0,0 @@
|
|||
#ifndef _TIMER_H__
|
||||
#define _TIMER_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <sys/timerfd.h>
|
||||
|
||||
typedef void (*timer_callback_t)(void *data);
|
||||
|
||||
extern int timer_init(int max_num);
|
||||
extern void timer_deinit(void);
|
||||
extern int timer_add(struct itimerspec *itimespec, int repeat, timer_callback_t cb, void *data);
|
||||
extern int timer_del(int timerfd);
|
||||
extern int timer_count(void);
|
||||
extern int timer_clear(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _TIMER_H__
|
||||
|
||||
Loading…
Reference in New Issue