From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id 7DF202CB59 for ; Tue, 30 Apr 2019 18:31:30 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id LZ10AuhIDF4X for ; Tue, 30 Apr 2019 18:31:30 -0400 (EDT) Received: from smtpng3.m.smailru.net (smtpng3.m.smailru.net [94.100.177.149]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id BE9D72C996 for ; Tue, 30 Apr 2019 18:31:29 -0400 (EDT) From: Vladislav Shpilevoy Subject: [tarantool-patches] [PATCH 1/5] swim: do not use ev_timer_start Date: Wed, 1 May 2019 01:31:23 +0300 Message-Id: <55eb3963102ddf0f83e0358d7041d6e2fabd729c.1556663421.git.v.shpilevoy@tarantool.org> In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-Help: List-Unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-Subscribe: List-Owner: List-post: List-Archive: To: tarantool-patches@freelists.org Cc: kostja@tarantool.org Appeared that libev changes 'ev_timer.at' field to a remaining time value, and it can't be used as a storage for a timeout. By the same reason ev_timer_start() can't be used to reuse a timer. On the contrary, 'ev_timer.repeat' is not touched by libev, and ev_timer_again() allows to reuse a timer. This patch replaces 'at' with 'repeat' and ev_timer_start() with ev_timer_again(). The bug was not detected by unit tests, because they implement their own event loop and do not change ev_timer.at. Now they do to prevent a regression. Part of #3234 --- src/lib/swim/swim.c | 28 +++++++++++----------------- src/lib/swim/swim.h | 4 ---- src/lib/swim/swim_ev.c | 6 ++++++ src/lib/swim/swim_ev.h | 3 +++ test/unit/swim_test_ev.c | 11 +++++++++++ 5 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/lib/swim/swim.c b/src/lib/swim/swim.c index 68b87b120..dfee16493 100644 --- a/src/lib/swim/swim.c +++ b/src/lib/swim/swim.c @@ -496,7 +496,7 @@ swim_wait_ack(struct swim *swim, struct swim_member *member, bool was_ping_indirect) { if (heap_node_is_stray(&member->in_wait_ack_heap)) { - double timeout = swim->wait_ack_tick.at; + double timeout = swim->wait_ack_tick.repeat; /* * Direct ping is two trips: PING + ACK. * Indirect ping is four trips: PING, @@ -507,7 +507,7 @@ swim_wait_ack(struct swim *swim, struct swim_member *member, timeout *= 2; member->ping_deadline = swim_time() + timeout; wait_ack_heap_insert(&swim->wait_ack_heap, member); - swim_ev_timer_start(loop(), &swim->wait_ack_tick); + swim_ev_timer_again(loop(), &swim->wait_ack_tick); } } @@ -767,7 +767,7 @@ swim_new_member(struct swim *swim, const struct sockaddr_in *addr, return NULL; } if (mh_size(swim->members) > 1) - swim_ev_timer_start(loop(), &swim->round_tick); + swim_ev_timer_again(loop(), &swim->round_tick); /* Dissemination component. */ swim_on_member_update(swim, member); @@ -1072,7 +1072,7 @@ swim_complete_step(struct swim_task *task, (void) rc; (void) task; struct swim *swim = swim_by_scheduler(scheduler); - swim_ev_timer_start(loop(), &swim->round_tick); + swim_ev_timer_again(loop(), &swim->round_tick); /* * It is possible that the original member was deleted * manually during the task execution. @@ -1239,7 +1239,7 @@ swim_check_acks(struct ev_loop *loop, struct ev_timer *t, int events) struct swim_member *m; while ((m = wait_ack_heap_top(&swim->wait_ack_heap)) != NULL) { if (current_time < m->ping_deadline) { - swim_ev_timer_start(loop, t); + swim_ev_timer_again(loop, t); return; } wait_ack_heap_pop(&swim->wait_ack_heap); @@ -1635,7 +1635,7 @@ swim_new(void) } rlist_create(&swim->round_queue); swim_ev_timer_init(&swim->round_tick, swim_begin_step, - HEARTBEAT_RATE_DEFAULT, 0); + 0, HEARTBEAT_RATE_DEFAULT); swim->round_tick.data = (void *) swim; swim_task_create(&swim->round_step_task, swim_complete_step, NULL, "round packet"); @@ -1644,7 +1644,7 @@ swim_new(void) /* Failure detection component. */ wait_ack_heap_create(&swim->wait_ack_heap); swim_ev_timer_init(&swim->wait_ack_tick, swim_check_acks, - ACK_TIMEOUT_DEFAULT, 0); + 0, ACK_TIMEOUT_DEFAULT); swim->wait_ack_tick.data = (void *) swim; swim->gc_mode = SWIM_GC_ON; @@ -1737,11 +1737,11 @@ swim_cfg(struct swim *swim, const char *uri, double heartbeat_rate, } else { addr = swim->self->addr; } - if (swim->round_tick.at != heartbeat_rate && heartbeat_rate > 0) - swim_ev_timer_set(&swim->round_tick, heartbeat_rate, 0); + if (swim->round_tick.repeat != heartbeat_rate && heartbeat_rate > 0) + swim_ev_timer_set(&swim->round_tick, 0, heartbeat_rate); - if (swim->wait_ack_tick.at != ack_timeout && ack_timeout > 0) - swim_ev_timer_set(&swim->wait_ack_tick, ack_timeout, 0); + if (swim->wait_ack_tick.repeat != ack_timeout && ack_timeout > 0) + swim_ev_timer_set(&swim->wait_ack_tick, 0, ack_timeout); if (new_self != NULL) { swim->self->status = MEMBER_LEFT; @@ -1763,12 +1763,6 @@ swim_set_codec(struct swim *swim, enum crypto_algo algo, const char *key) return swim_scheduler_set_codec(&swim->scheduler, algo, key); } -double -swim_ack_timeout(const struct swim *swim) -{ - return swim->wait_ack_tick.at; -} - bool swim_is_configured(const struct swim *swim) { diff --git a/src/lib/swim/swim.h b/src/lib/swim/swim.h index 5abbe8c33..653e45be7 100644 --- a/src/lib/swim/swim.h +++ b/src/lib/swim/swim.h @@ -101,10 +101,6 @@ swim_cfg(struct swim *swim, const char *uri, double heartbeat_rate, double ack_timeout, enum swim_gc_mode gc_mode, const struct tt_uuid *uuid); -/** SWIM's ACK timeout, previously set via @sa swim_cfg. */ -double -swim_ack_timeout(const struct swim *swim); - /** Set payload to disseminate over the cluster. */ int swim_set_payload(struct swim *swim, const char *payload, uint16_t payload_size); diff --git a/src/lib/swim/swim_ev.c b/src/lib/swim/swim_ev.c index f7c464426..49c8c273b 100644 --- a/src/lib/swim/swim_ev.c +++ b/src/lib/swim/swim_ev.c @@ -44,6 +44,12 @@ swim_ev_timer_start(struct ev_loop *loop, struct ev_timer *watcher) ev_timer_start(loop, watcher); } +void +swim_ev_timer_again(struct ev_loop *loop, struct ev_timer *watcher) +{ + ev_timer_again(loop, watcher); +} + void swim_ev_timer_stop(struct ev_loop *loop, struct ev_timer *watcher) { diff --git a/src/lib/swim/swim_ev.h b/src/lib/swim/swim_ev.h index 34394ef47..0fe550523 100644 --- a/src/lib/swim/swim_ev.h +++ b/src/lib/swim/swim_ev.h @@ -46,6 +46,9 @@ swim_time(void); void swim_ev_timer_start(struct ev_loop *loop, struct ev_timer *watcher); +void +swim_ev_timer_again(struct ev_loop *loop, struct ev_timer *watcher); + void swim_ev_timer_stop(struct ev_loop *loop, struct ev_timer *watcher); diff --git a/test/unit/swim_test_ev.c b/test/unit/swim_test_ev.c index 135f20107..16fd87c78 100644 --- a/test/unit/swim_test_ev.c +++ b/test/unit/swim_test_ev.c @@ -184,6 +184,7 @@ swim_timer_event_process(struct swim_event *e, struct ev_loop *loop) assert(e->type == SWIM_EVENT_TIMER); struct ev_watcher *w = ((struct swim_timer_event *) e)->watcher; swim_timer_event_delete(e); + ((struct ev_timer *) w)->at = 0; ev_invoke(loop, w, EV_TIMER); } @@ -265,6 +266,16 @@ swim_ev_timer_start(struct ev_loop *loop, struct ev_timer *base) swim_timer_event_new((struct ev_watcher *) base, base->at); } +void +swim_ev_timer_again(struct ev_loop *loop, struct ev_timer *base) +{ + (void) loop; + if (swim_event_by_ev((struct ev_watcher *) base) != NULL) + return; + /* Create the periodic watcher and one event. */ + swim_timer_event_new((struct ev_watcher *) base, base->repeat); +} + /** Time stop cancels the event if the timer is active. */ void swim_ev_timer_stop(struct ev_loop *loop, struct ev_timer *base) -- 2.20.1 (Apple Git-117)