https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=bf915420042eadf29622c9a7b7ab12221f238fe5
commit bf915420042eadf29622c9a7b7ab12221f238fe5 Author: Takashi Yano <[email protected]> Date: Wed Jan 25 18:30:50 2023 +0900 Cygwin: dsp: Fix hang on close() if another thread calls write(). fhandler_dev_dsp (OSS) has a problem that waitforallsent(), which is called from close(), falls into infinite loop if another thread calls write() accidentally after close(). This patch fixes the issue. Reviewed-by: Corinna Vinschen <[email protected]> Signed-off-by: Takashi Yano <[email protected]> Diff: --- winsup/cygwin/fhandler/dsp.cc | 9 +++++++++ winsup/cygwin/local_includes/fhandler.h | 1 + 2 files changed, 10 insertions(+) diff --git a/winsup/cygwin/fhandler/dsp.cc b/winsup/cygwin/fhandler/dsp.cc index 8798cf876..cfbf6bec7 100644 --- a/winsup/cygwin/fhandler/dsp.cc +++ b/winsup/cygwin/fhandler/dsp.cc @@ -1093,6 +1093,8 @@ fhandler_dev_dsp::open (int flags, mode_t) debug_printf ("ACCMODE=%y audio_in=%d audio_out=%d, err=%d, ret=%d", flags & O_ACCMODE, num_in, num_out, err, ret); + if (ret) + being_closed = false; return ret; } @@ -1106,6 +1108,12 @@ fhandler_dev_dsp::_write (const void *ptr, size_t len) int len_s = len; const char *ptr_s = static_cast <const char *> (ptr); + if (being_closed) + { + set_errno (EBADF); + return -1; + } + if (audio_out_) /* nothing to do */; else if (IS_WRITE ()) @@ -1207,6 +1215,7 @@ int fhandler_dev_dsp::close () { debug_printf ("audio_in=%p audio_out=%p", audio_in_, audio_out_); + being_closed = true; close_audio_in (); close_audio_out (); return fhandler_base::close (); diff --git a/winsup/cygwin/local_includes/fhandler.h b/winsup/cygwin/local_includes/fhandler.h index 113e40293..f3dd1b5a4 100644 --- a/winsup/cygwin/local_includes/fhandler.h +++ b/winsup/cygwin/local_includes/fhandler.h @@ -2762,6 +2762,7 @@ class fhandler_dev_dsp: public fhandler_base int audiochannels_; Audio_out *audio_out_; Audio_in *audio_in_; + bool being_closed; public: fhandler_dev_dsp (); fhandler_dev_dsp *base () const {return (fhandler_dev_dsp *)archetype;}
