From b0c7854d126b697c9cd9fbf645f60e0e2391ad5d Mon Sep 17 00:00:00 2001 From: fengzero Date: Fri, 22 Sep 2023 09:52:26 +0000 Subject: [PATCH] fix(timer): stop after callback done --- src/event/event_linux.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/event/event_linux.c b/src/event/event_linux.c index ff7011cf..079bc80c 100644 --- a/src/event/event_linux.c +++ b/src/event/event_linux.c @@ -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; }