From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> To: tarantool-patches@freelists.org Cc: kostja@tarantool.org Subject: [tarantool-patches] [PATCH 5/6] test: differentiate blocked and closed swim fake fds Date: Wed, 20 Mar 2019 13:49:18 +0300 [thread overview] Message-ID: <aaafcbb19c32bd4358a55c4249fd37d098a606d6.1553078631.git.v.shpilevoy@tarantool.org> (raw) In-Reply-To: <cover.1553078631.git.v.shpilevoy@tarantool.org> In-Reply-To: <cover.1553078631.git.v.shpilevoy@tarantool.org> SWIM's fake file descriptors were implemented to test SWIM with virtual time and fully controlled network with immediate packet delivery. One of their features - API to block a file descriptor and test various failures about it. But blocked fake fd looks the same as closed fd, and it can confuse new test's author. Now if an fd is not unblocked at the end of a test, it leads to a crash. This commit fixes that via adding explicit difference between blocked and closed fd. Part of #3234 --- test/unit/swim_test_transport.c | 53 +++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/test/unit/swim_test_transport.c b/test/unit/swim_test_transport.c index d6591e969..d1c3e97d7 100644 --- a/test/unit/swim_test_transport.c +++ b/test/unit/swim_test_transport.c @@ -90,10 +90,17 @@ struct swim_fd { /** File descriptor number visible to libev. */ int evfd; /** - * Link in the list of opened descriptors. Used to feed - * them all EV_WRITE. + * True, if the descriptor is opened and can receive new + * messages. Regardless of blocked or not. In case of + * blocked, new messages are queued, but not delivered. */ - struct rlist in_opened; + bool is_opened; + + /** + * Link in the list of opened and non-blocked descriptors. + * Used to feed them all EV_WRITE. + */ + struct rlist in_active; /** Queue of received, but not processed packets. */ struct rlist recv_queue; /** Queue of sent, but not received packets. */ @@ -103,23 +110,22 @@ struct swim_fd { /** Table of fake file descriptors. */ static struct swim_fd swim_fd[FAKE_FD_NUMBER]; /** - * List of opened file descriptors. Used to avoid fullscan of the + * List of active file descriptors. Used to avoid fullscan of the * table. */ -static RLIST_HEAD(swim_fd_opened); +static RLIST_HEAD(swim_fd_active); /** Open a fake file descriptor. */ static inline int swim_fd_open(struct swim_fd *fd) { - if (! rlist_empty(&fd->in_opened)) { + if (fd->is_opened) { errno = EADDRINUSE; diag_set(SocketError, "test_socket:1", "bind"); return -1; } - rlist_add_tail_entry(&swim_fd_opened, fd, in_opened); - rlist_create(&fd->recv_queue); - rlist_create(&fd->send_queue); + fd->is_opened = true; + rlist_add_tail_entry(&swim_fd_active, fd, in_active); return 0; } @@ -127,12 +133,15 @@ swim_fd_open(struct swim_fd *fd) static inline void swim_fd_close(struct swim_fd *fd) { + if (! fd->is_opened) + return; struct swim_test_packet *i, *tmp; rlist_foreach_entry_safe(i, &fd->recv_queue, in_queue, tmp) swim_test_packet_delete(i); rlist_foreach_entry_safe(i, &fd->send_queue, in_queue, tmp) swim_test_packet_delete(i); - rlist_del_entry(fd, in_opened); + rlist_del_entry(fd, in_active); + fd->is_opened = false; } void @@ -140,7 +149,8 @@ swim_test_transport_init(void) { for (int i = 0, evfd = FAKE_FD_BASE; i < FAKE_FD_NUMBER; ++i, ++evfd) { swim_fd[i].evfd = evfd; - rlist_create(&swim_fd[i].in_opened); + swim_fd[i].is_opened = false; + rlist_create(&swim_fd[i].in_active); rlist_create(&swim_fd[i].recv_queue); rlist_create(&swim_fd[i].send_queue); } @@ -172,6 +182,7 @@ swim_transport_send(struct swim_transport *transport, const void *data, swim_test_packet_new(data, size, &transport->addr, (const struct sockaddr_in *) addr); struct swim_fd *src = &swim_fd[transport->fd - FAKE_FD_BASE]; + assert(src->is_opened); rlist_add_tail_entry(&src->send_queue, p, in_queue); return size; } @@ -188,6 +199,7 @@ swim_transport_recv(struct swim_transport *transport, void *buffer, size_t size, * Pop a packet from a receving queue. */ struct swim_fd *dst = &swim_fd[transport->fd - FAKE_FD_BASE]; + assert(dst->is_opened); struct swim_test_packet *p = rlist_shift_entry(&dst->recv_queue, struct swim_test_packet, in_queue); @@ -236,16 +248,16 @@ void swim_test_transport_block_fd(int fd) { struct swim_fd *sfd = &swim_fd[fd - FAKE_FD_BASE]; - assert(! rlist_empty(&sfd->in_opened)); - rlist_del_entry(sfd, in_opened); + assert(! rlist_empty(&sfd->in_active)); + rlist_del_entry(sfd, in_active); } void swim_test_transport_unblock_fd(int fd) { struct swim_fd *sfd = &swim_fd[fd - FAKE_FD_BASE]; - assert(rlist_empty(&sfd->in_opened)); - rlist_add_tail_entry(&swim_fd_opened, sfd, in_opened); + if (sfd->is_opened && rlist_empty(&sfd->in_active)) + rlist_add_tail_entry(&swim_fd_active, sfd, in_active); } /** Send one packet to destination's recv queue. */ @@ -257,8 +269,11 @@ swim_fd_send_packet(struct swim_fd *fd) struct swim_test_packet *p = rlist_shift_entry(&fd->send_queue, struct swim_test_packet, in_queue); - int dst_i = ntohs(p->dst.sin_port); - rlist_add_tail_entry(&swim_fd[dst_i].recv_queue, p, in_queue); + struct swim_fd *dst = &swim_fd[ntohs(p->dst.sin_port)]; + if (dst->is_opened) + rlist_add_tail_entry(&dst->recv_queue, p, in_queue); + else + swim_test_packet_delete(p); } void @@ -269,11 +284,11 @@ swim_transport_do_loop_step(struct ev_loop *loop) * Reversed because libev invokes events in reversed * order. So this reverse + libev reverse = normal order. */ - rlist_foreach_entry_reverse(fd, &swim_fd_opened, in_opened) { + rlist_foreach_entry_reverse(fd, &swim_fd_active, in_active) { swim_fd_send_packet(fd); ev_feed_fd_event(loop, fd->evfd, EV_WRITE); } - rlist_foreach_entry_reverse(fd, &swim_fd_opened, in_opened) { + rlist_foreach_entry_reverse(fd, &swim_fd_active, in_active) { if (!rlist_empty(&fd->recv_queue)) ev_feed_fd_event(loop, fd->evfd, EV_READ); } -- 2.17.2 (Apple Git-113)
next prev parent reply other threads:[~2019-03-20 10:49 UTC|newest] Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-03-20 10:49 [tarantool-patches] [PATCH 0/6] SWIM failure detection draft Vladislav Shpilevoy 2019-03-20 10:49 ` [tarantool-patches] [PATCH 1/6] swim: follow-ups for SWIM anti-entropy Vladislav Shpilevoy 2019-03-29 8:27 ` [tarantool-patches] " Konstantin Osipov 2019-03-29 10:19 ` Vladislav Shpilevoy 2019-03-20 10:49 ` [tarantool-patches] [PATCH 2/6] test: introduce breakpoints for swim's event loop Vladislav Shpilevoy 2019-03-29 18:20 ` [tarantool-patches] " Konstantin Osipov 2019-04-02 12:25 ` Vladislav Shpilevoy 2019-04-02 19:16 ` Vladislav Shpilevoy 2019-04-02 20:40 ` Konstantin Osipov 2019-04-02 21:26 ` Vladislav Shpilevoy 2019-03-20 10:49 ` [tarantool-patches] [PATCH 3/6] test: remove swim_unblock_fd event from swim test harness Vladislav Shpilevoy 2019-03-29 18:22 ` [tarantool-patches] " Konstantin Osipov 2019-04-02 21:26 ` Vladislav Shpilevoy 2019-03-20 10:49 ` [tarantool-patches] [PATCH 4/6] swim: expose enum swim_member_status to public API Vladislav Shpilevoy 2019-03-29 18:24 ` [tarantool-patches] " Konstantin Osipov 2019-04-02 12:25 ` Vladislav Shpilevoy 2019-04-02 13:17 ` Konstantin Osipov 2019-04-02 21:26 ` Vladislav Shpilevoy 2019-03-20 10:49 ` Vladislav Shpilevoy [this message] 2019-03-29 18:25 ` [tarantool-patches] Re: [PATCH 5/6] test: differentiate blocked and closed swim fake fds Konstantin Osipov 2019-04-02 21:26 ` Vladislav Shpilevoy 2019-03-20 10:49 ` [tarantool-patches] [PATCH 6/6] [RAW] swim: introduce failure detection component Vladislav Shpilevoy 2019-03-29 18:59 ` [tarantool-patches] " Konstantin Osipov 2019-04-02 12:25 ` Vladislav Shpilevoy 2019-04-04 10:20 ` Vladislav Shpilevoy 2019-04-04 12:45 ` Konstantin Osipov 2019-04-04 13:57 ` Vladislav Shpilevoy 2019-04-04 16:14 ` Vladimir Davydov 2019-04-04 16:47 ` Vladislav Shpilevoy 2019-03-27 19:28 ` [tarantool-patches] [PATCH 7/6] swim: make swim_upsert_member returning two values Vladislav Shpilevoy 2019-03-28 8:52 ` [tarantool-patches] " Konstantin Osipov 2019-03-28 11:52 ` 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=aaafcbb19c32bd4358a55c4249fd37d098a606d6.1553078631.git.v.shpilevoy@tarantool.org \ --to=v.shpilevoy@tarantool.org \ --cc=kostja@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='Re: [tarantool-patches] [PATCH 5/6] test: differentiate blocked and closed swim fake fds' \ /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