From 2f168f68e819b3adeee9ce931f9469b680049e4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Andr=C3=A9=20Vadla=20Ravn=C3=A5s?= Date: Fri, 6 Sep 2024 15:09:25 +0200 Subject: [PATCH] network-stack: Fix deadlock in perform_on_lwip_thread() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Where in the case of already being on the lwIP thread, we would enqueue the request and then perform whichever is the oldest pending request. So when there was already one or more requests pending, we would perform that request instead. Then next we would join() our request, assuming it had completed, and end up deadlocking the lwIP thread. Kudos to @mrmacete for reporting and helping track this one down. Co-authored-by: Håvard Sørbø --- src/fruity/network-stack.vala | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/fruity/network-stack.vala b/src/fruity/network-stack.vala index 844469eca..ceff444b1 100644 --- a/src/fruity/network-stack.vala +++ b/src/fruity/network-stack.vala @@ -288,13 +288,13 @@ namespace Frida.Fruity { internal LWIP.ErrorCode perform_on_lwip_thread (owned WorkFunc work) { var req = new Request ((owned) work); - lock (requests) - requests.offer (req); - - if (Thread.self () != lwip_thread) + if (Thread.self () == lwip_thread) { + perform_request (req); + } else { + lock (requests) + requests.offer (req); LWIP.Runtime.schedule (perform_next_request); - else - perform_next_request (); + } return req.join (); } @@ -307,6 +307,10 @@ namespace Frida.Fruity { lock (requests) req = requests.poll (); + perform_request (res); + } + + private void perform_request (Request req) { LWIP.ErrorCode err = req.work (); req.complete (err); }