fix(timer): stop after callback done

This commit is contained in:
fengzero
2023-09-22 09:52:26 +00:00
parent 555e77fe5b
commit b0c7854d12
+23 -9
View File
@@ -41,6 +41,8 @@ struct neu_event_timer {
struct event_data * event_data;
struct itimerspec value;
neu_event_timer_type_e type;
nng_mtx * mtx;
bool stop;
};
struct neu_event_io {
@@ -130,22 +132,27 @@ static void *event_loop(void *arg)
switch (data->type) {
case TIMER:
nng_mtx_lock(data->ctx.timer.mtx);
if ((event.events & EPOLLIN) == EPOLLIN) {
uint64_t t;
ssize_t size = read(data->fd, &t, sizeof(t));
(void) size;
if (data->ctx.timer.type == NEU_EVENT_TIMER_BLOCK) {
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, data->fd, NULL);
ret = data->callback.timer(data->usr_data);
timerfd_settime(data->fd, 0, &data->ctx.timer.value, NULL);
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, data->fd, &event);
} else {
ret = data->callback.timer(data->usr_data);
if (!data->ctx.timer.stop) {
if (data->ctx.timer.type == NEU_EVENT_TIMER_BLOCK) {
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, data->fd, NULL);
ret = data->callback.timer(data->usr_data);
timerfd_settime(data->fd, 0, &data->ctx.timer.value,
NULL);
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, data->fd, &event);
} else {
ret = data->callback.timer(data->usr_data);
}
}
}
nng_mtx_unlock(data->ctx.timer.mtx);
break;
case IO:
if ((event.events & EPOLLHUP) == EPOLLHUP) {
@@ -230,6 +237,8 @@ neu_event_timer_t *neu_event_add_timer(neu_events_t * events,
timer_ctx->value = value;
timer_ctx->fd = timer_fd;
timer_ctx->type = timer.type;
timer_ctx->stop = false;
nng_mtx_alloc(&timer_ctx->mtx);
ret = epoll_ctl(events->epoll_fd, EPOLL_CTL_ADD, timer_fd, &event);
@@ -248,10 +257,15 @@ int neu_event_del_timer(neu_events_t *events, neu_event_timer_t *timer)
zlog_notice(neuron, "del timer: %d from epoll: %d", timer->fd,
events->epoll_fd);
timer->stop = true;
epoll_ctl(events->epoll_fd, EPOLL_CTL_DEL, timer->fd, NULL);
close(timer->fd);
free_event(events, timer->event_data->index);
nng_mtx_lock(timer->mtx);
close(timer->fd);
nng_mtx_unlock(timer->mtx);
nng_mtx_free(timer->mtx);
free_event(events, timer->event_data->index);
return 0;
}