From 6f13ccf7c376b66cd7254aecb51ac162a58e274f Mon Sep 17 00:00:00 2001
From: Olivier Basson <olivier@camtrace.com>
Date: Wed, 29 Mar 2017 08:22:54 +0800
Subject: [PATCH] ev: stop event listeners during context destroy

I think I've found a bug in libev backend, in function lws_libev_io(). I'm using latest version from master branch.

When deleting a context with active connections via lws_context_destroy(), context->being_destroyed is set to 1 early in the function, before the loop calling lws_close_free_wsi() on each active connection.
lws_close_free_wsi() calls remove_wsi_socket_from_fds(), which calls lws_libev_io(), and here is my problem :

lws_libev_io() returns without doing anything if context->being_destroyed is set, so libev callbacks for deleted connections file descriptors stay registered after context is destroyed, which may lead to segfault/undefined behaviour if these file descriptors get reused later (which would trigger the callbacks).

I think the "if (!pt->io_loop_ev || context->being_destroyed) return;" statement should be replaced with " if (!pt->io_loop_ev) return;"

This fixes the problem for me and I have not seen any side effect yet. Moreover, libuv backend does not have such a test.
---
 lib/libev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/libev.c b/lib/libev.c
index 71834a2d..e422d7e5 100644
--- a/lib/libev.c
+++ b/lib/libev.c
@@ -190,7 +190,7 @@ lws_libev_io(struct lws *wsi, int flags)
 	if (!LWS_LIBEV_ENABLED(context))
 		return;
 
-	if (!pt->io_loop_ev || context->being_destroyed)
+	if (!pt->io_loop_ev)
 		return;
 
 	assert((flags & (LWS_EV_START | LWS_EV_STOP)) &&
-- 
GitLab