From bbf0ace06cf0c2b911afef98956cdc8f53f81f03 Mon Sep 17 00:00:00 2001 From: Falk Werner Date: Tue, 30 Apr 2019 19:45:56 +0200 Subject: [PATCH] fixes resource leak: pending timer after cleanup proxy --- lib/webfuse/adapter/impl/jsonrpc/proxy.c | 14 ++++++++--- test/adapter/jsonrpc/test_proxy.cc | 30 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/lib/webfuse/adapter/impl/jsonrpc/proxy.c b/lib/webfuse/adapter/impl/jsonrpc/proxy.c index 06689a2..ec0da2e 100644 --- a/lib/webfuse/adapter/impl/jsonrpc/proxy.c +++ b/lib/webfuse/adapter/impl/jsonrpc/proxy.c @@ -85,13 +85,21 @@ void wf_impl_jsonrpc_proxy_init( void wf_impl_jsonrpc_proxy_cleanup( struct wf_impl_jsonrpc_proxy * proxy) { - wf_impl_timer_cleanup(&proxy->request.timer); - if (proxy->request.is_pending) { - proxy->request.finished(proxy->request.user_data, WF_BAD, NULL); + void * user_data = proxy->request.user_data; + wf_impl_jsonrpc_proxy_finished_fn * finished = proxy->request.finished; + proxy->request.is_pending = false; + proxy->request.finished = NULL; + proxy->request.user_data = NULL; + proxy->request.id = 0; + wf_impl_timer_cancel(&proxy->request.timer); + + finished(user_data, WF_BAD, NULL); } + + wf_impl_timer_cleanup(&proxy->request.timer); } void wf_impl_jsonrpc_proxy_invoke( diff --git a/test/adapter/jsonrpc/test_proxy.cc b/test/adapter/jsonrpc/test_proxy.cc index f80409d..1355c4e 100644 --- a/test/adapter/jsonrpc/test_proxy.cc +++ b/test/adapter/jsonrpc/test_proxy.cc @@ -309,6 +309,36 @@ TEST(jsonrpc_proxy, timeout) wf_impl_timeout_manager_cleanup(&timeout_manager); } +TEST(jsonrpc_proxy, cleanup_pending_request) +{ + struct wf_impl_timeout_manager timeout_manager; + wf_impl_timeout_manager_init(&timeout_manager); + + SendContext send_context; + void * send_data = reinterpret_cast(&send_context); + struct wf_impl_jsonrpc_proxy proxy; + wf_impl_jsonrpc_proxy_init(&proxy, &timeout_manager, 10, &jsonrpc_send, send_data); + + FinishedContext finished_context; + void * finished_data = reinterpret_cast(&finished_context); + wf_impl_jsonrpc_proxy_invoke(&proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42); + + ASSERT_TRUE(send_context.is_called); + ASSERT_TRUE(json_is_object(send_context.response)); + + ASSERT_FALSE(finished_context.is_called); + ASSERT_NE(nullptr, timeout_manager.timers); + + wf_impl_jsonrpc_proxy_cleanup(&proxy); + + ASSERT_TRUE(finished_context.is_called); + ASSERT_EQ(nullptr, timeout_manager.timers); + + wf_impl_timeout_manager_cleanup(&timeout_manager); +} + + + TEST(jsonrpc_proxy, notify) { struct wf_impl_timeout_manager timeout_manager;