From 13c65c43c24015f75b6488dc476b8d7b22c84f18 Mon Sep 17 00:00:00 2001 From: Ken Brown Date: Mon, 4 May 2020 11:36:20 -0400 Subject: [PATCH] Cygwin: FIFO: dup/fork/exec: make sure child starts unlocked There can be deadlocks if the child starts with its fifo_client_lock in the locked state. --- winsup/cygwin/fhandler_fifo.cc | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index f61e2fe72..4904a535d 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -981,6 +981,9 @@ fhandler_fifo::dup (fhandler_base *child, int flags) } if (reader) { + /* Make sure the child starts unlocked. */ + fhf->fifo_client_unlock (); + fifo_client_lock (); for (i = 0; i < nhandlers; i++) { @@ -1025,20 +1028,32 @@ fhandler_fifo::fixup_after_fork (HANDLE parent) fhandler_base::fixup_after_fork (parent); fork_fixup (parent, read_ready, "read_ready"); fork_fixup (parent, write_ready, "write_ready"); - fifo_client_lock (); - for (int i = 0; i < nhandlers; i++) - fork_fixup (parent, fc_handler[i].h, "fc_handler[].h"); - fifo_client_unlock (); - if (reader && !listen_client ()) - debug_printf ("failed to start lct, %E"); + if (reader) + { + /* Make sure the child starts unlocked. */ + fifo_client_unlock (); + + fifo_client_lock (); + for (int i = 0; i < nhandlers; i++) + fork_fixup (parent, fc_handler[i].h, "fc_handler[].h"); + fifo_client_unlock (); + if (!listen_client ()) + debug_printf ("failed to start lct, %E"); + } } void fhandler_fifo::fixup_after_exec () { fhandler_base::fixup_after_exec (); - if (reader && !listen_client ()) - debug_printf ("failed to start lct, %E"); + if (reader && !close_on_exec ()) + { + /* Make sure the child starts unlocked. */ + fifo_client_unlock (); + + if (!listen_client ()) + debug_printf ("failed to start lct, %E"); + } } void -- 2.43.5