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 <corinna@vinschen.de>
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
This commit is contained in:
Takashi Yano 2023-01-25 18:30:50 +09:00
parent cad3913ed8
commit bf91542004
2 changed files with 10 additions and 0 deletions

View File

@ -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 ();

View File

@ -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;}