diff options
author | Ken Brown <kbrown@cornell.edu> | 2020-05-04 11:36:20 -0400 |
---|---|---|
committer | Ken Brown <kbrown@cornell.edu> | 2020-05-08 06:32:00 -0400 |
commit | 13c65c43c24015f75b6488dc476b8d7b22c84f18 (patch) | |
tree | 3b3c12696f77613251de08bc79be68ccf587bda2 | |
parent | 624fda1e96adf3c4de745115d97fe254d4be53e8 (diff) | |
download | cygnal-13c65c43c24015f75b6488dc476b8d7b22c84f18.tar.gz cygnal-13c65c43c24015f75b6488dc476b8d7b22c84f18.tar.bz2 cygnal-13c65c43c24015f75b6488dc476b8d7b22c84f18.zip |
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.
-rw-r--r-- | winsup/cygwin/fhandler_fifo.cc | 31 |
1 files 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 |