From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
To: tarantool-patches@freelists.org
Cc: kostja@tarantool.org
Subject: [tarantool-patches] [PATCH 1/5] swim: do not use ev_timer_start
Date: Wed, 1 May 2019 01:31:23 +0300 [thread overview]
Message-ID: <55eb3963102ddf0f83e0358d7041d6e2fabd729c.1556663421.git.v.shpilevoy@tarantool.org> (raw)
In-Reply-To: <cover.1556663421.git.v.shpilevoy@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)
next prev parent reply other threads:[~2019-04-30 22:31 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-30 22:31 [tarantool-patches] [PATCH 0/5] swim lua preparation Vladislav Shpilevoy
2019-04-30 22:31 ` Vladislav Shpilevoy [this message]
2019-05-01 5:09 ` [tarantool-patches] Re: [PATCH 1/5] swim: do not use ev_timer_start Konstantin Osipov
2019-04-30 22:31 ` [tarantool-patches] [PATCH 2/5] swim: introduce member reference API Vladislav Shpilevoy
2019-05-01 5:15 ` [tarantool-patches] " Konstantin Osipov
2019-05-02 15:10 ` Vladislav Shpilevoy
2019-05-02 15:46 ` Konstantin Osipov
2019-05-02 17:32 ` Vladislav Shpilevoy
2019-04-30 22:31 ` [tarantool-patches] [PATCH 3/5] sio: return 'no host' flag from sio_uri_to_addr() Vladislav Shpilevoy
2019-05-01 5:18 ` [tarantool-patches] " Konstantin Osipov
2019-04-30 22:31 ` [tarantool-patches] [PATCH 4/5] swim: allow to omit host in URI Vladislav Shpilevoy
2019-05-01 5:20 ` [tarantool-patches] " Konstantin Osipov
2019-05-02 15:10 ` Vladislav Shpilevoy
2019-04-30 22:31 ` [tarantool-patches] [PATCH 5/5] swim: explicitly stop old ev_io input/output on rebind Vladislav Shpilevoy
2019-05-01 5:21 ` [tarantool-patches] " Konstantin Osipov
2019-05-02 17:32 ` [tarantool-patches] Re: [PATCH 0/5] swim lua preparation Vladislav Shpilevoy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=55eb3963102ddf0f83e0358d7041d6e2fabd729c.1556663421.git.v.shpilevoy@tarantool.org \
--to=v.shpilevoy@tarantool.org \
--cc=kostja@tarantool.org \
--cc=tarantool-patches@freelists.org \
--subject='Re: [tarantool-patches] [PATCH 1/5] swim: do not use ev_timer_start' \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox