From 93f904f601bb21dbcc8e6badd05970824990285f Mon Sep 17 00:00:00 2001
From: Sungtae Kim <pchero21@gmail.com>
Date: Wed, 17 Jan 2018 02:05:45 +0100
Subject: [PATCH] libevent: fix memory leak

- Added event free function for accept.
---
 lib/context.c               | 19 +++++++++++++------
 lib/event-libs/libevent.c   | 13 +++++++++++++
 lib/libwebsockets.c         |  2 ++
 lib/private-libwebsockets.h |  3 +++
 4 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/lib/context.c b/lib/context.c
index 28db7aa4..67636c34 100644
--- a/lib/context.c
+++ b/lib/context.c
@@ -958,6 +958,16 @@ lws_create_event_pipes(struct lws_context *context)
 	return 0;
 }
 
+static void
+lws_destroy_event_pipe(struct lws *wsi)
+{
+	lws_plat_pipe_close(wsi);
+	remove_wsi_socket_from_fds(wsi);
+	lws_libevent_destroy(wsi);
+	wsi->context->count_wsi_allocated--;
+	lws_free(wsi);
+}
+
 LWS_VISIBLE struct lws_context *
 lws_create_context(struct lws_context_creation_info *info)
 {
@@ -1682,12 +1692,9 @@ lws_context_destroy(struct lws_context *context)
 			if (!wsi)
 				continue;
 
-			if (wsi->event_pipe) {
-				lws_plat_pipe_close(wsi);
-				remove_wsi_socket_from_fds(wsi);
-				lws_free(wsi);
-				context->count_wsi_allocated--;
-			} else
+			if (wsi->event_pipe)
+				lws_destroy_event_pipe(wsi);
+			else
 				lws_close_free_wsi(wsi,
 					LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY
 					/* no protocol close */);
diff --git a/lib/event-libs/libevent.c b/lib/event-libs/libevent.c
index ad12ac51..61af5d3f 100644
--- a/lib/event-libs/libevent.c
+++ b/lib/event-libs/libevent.c
@@ -185,6 +185,19 @@ lws_libevent_accept(struct lws *new_wsi, lws_sock_file_fd_type desc)
 		(EV_WRITE | EV_PERSIST), lws_event_cb, &new_wsi->w_write);
 }
 
+LWS_VISIBLE void
+lws_libevent_destroy(struct lws *wsi)
+{
+	if (!wsi)
+		return;
+
+	if(wsi->w_read.event_watcher)
+		event_free(wsi->w_read.event_watcher);
+
+	if(wsi->w_write.event_watcher)
+		event_free(wsi->w_write.event_watcher);
+}
+
 LWS_VISIBLE void
 lws_libevent_io(struct lws *wsi, int flags)
 {
diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c
index 32157eff..bba1182a 100644
--- a/lib/libwebsockets.c
+++ b/lib/libwebsockets.c
@@ -124,6 +124,8 @@ lws_free_wsi(struct lws *wsi)
 	lws_ssl_remove_wsi_from_buffered_list(wsi);
 	lws_remove_from_timeout_list(wsi);
 
+	lws_libevent_destroy(wsi);
+
 	wsi->context->count_wsi_allocated--;
 	lwsl_debug("%s: %p, remaining wsi %d\n", __func__, wsi,
 			wsi->context->count_wsi_allocated);
diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h
index 04b312ca..a3c38e00 100644
--- a/lib/private-libwebsockets.h
+++ b/lib/private-libwebsockets.h
@@ -1275,6 +1275,8 @@ LWS_EXTERN void lws_feature_status_libuv(struct lws_context_creation_info *info)
 #if defined(LWS_WITH_LIBEVENT)
 LWS_EXTERN void
 lws_libevent_accept(struct lws *new_wsi, lws_sock_file_fd_type desc);
+LWS_VISIBLE void
+lws_libevent_destroy(struct lws *wsi);
 LWS_EXTERN void
 lws_libevent_io(struct lws *wsi, int flags);
 LWS_EXTERN int
@@ -1287,6 +1289,7 @@ lws_libevent_run(const struct lws_context *context, int tsi);
 LWS_EXTERN void lws_feature_status_libevent(struct lws_context_creation_info *info);
 #else
 #define lws_libevent_accept(_a, _b) ((void) 0)
+#define lws_libevent_destroy(_a) ((void) 0)
 #define lws_libevent_io(_a, _b) ((void) 0)
 #define lws_libevent_init_fd_table(_a) (0)
 #define lws_libevent_run(_a, _b) ((void) 0)
-- 
GitLab