Cygwin: dsp: Improve response time of select()/poll().

With this patch, the response time of select()/poll() has been
improved by utilizing semaphore (select_sem) just like pipe and
fifo. In addition, notification of exceptional conditions has
been added.

Fixes: 2c06014f12 ("Cygwin: dsp: Implement select()/poll().")
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
This commit is contained in:
Takashi Yano 2023-09-07 17:35:25 +09:00
parent 2c06014f12
commit 7ced682549
3 changed files with 27 additions and 5 deletions

View File

@ -536,6 +536,8 @@ inline void
fhandler_dev_dsp::Audio_out::callback_sampledone (WAVEHDR *pHdr)
{
Qisr2app_->send (pHdr);
ReleaseSemaphore (fh->get_select_sem (),
get_obj_handle_count (fh->get_select_sem ()) - 1, NULL);
}
bool
@ -994,6 +996,8 @@ inline void
fhandler_dev_dsp::Audio_in::callback_blockfull (WAVEHDR *pHdr)
{
Qisr2app_->send (pHdr);
ReleaseSemaphore (fh->get_select_sem (),
get_obj_handle_count (fh->get_select_sem ()) - 1, NULL);
}
static void CALLBACK
@ -1058,7 +1062,7 @@ fhandler_dev_dsp::fixup_after_exec ()
int
fhandler_dev_dsp::open (int flags, mode_t)
fhandler_dev_dsp::open (int flags, mode_t mode)
{
int ret = -1, err = 0;
UINT num_in = 0, num_out = 0;
@ -1093,6 +1097,8 @@ fhandler_dev_dsp::open (int flags, mode_t)
else
ret = open_null (flags);
select_sem = CreateSemaphore (sec_none_cloexec (mode), 0, INT32_MAX, NULL);
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 >= 0)
@ -1226,6 +1232,9 @@ fhandler_dev_dsp::close ()
being_closed = true;
close_audio_in ();
close_audio_out ();
ReleaseSemaphore (select_sem, get_obj_handle_count (select_sem) - 1, NULL);
CloseHandle (select_sem);
select_sem = NULL;
return fhandler_base::close ();
}

View File

@ -2875,8 +2875,9 @@ class fhandler_dev_dsp: public fhandler_base
select_record *select_write (select_stuff *);
select_record *select_except (select_stuff *);
bool read_ready();
bool write_ready();
bool read_ready ();
bool write_ready ();
bool is_closed () { return being_closed; };
};
class fhandler_virtual : public fhandler_base

View File

@ -2268,6 +2268,9 @@ peek_dsp (select_record *s, bool from_select)
if (s->write_selected)
if (s->write_ready || fh->write_ready ())
gotone += s->write_ready = true;
if (s->except_selected)
if (s->except_ready || fh->is_closed ())
gotone += s->except_ready = true;
return gotone;
}
@ -2296,7 +2299,7 @@ thread_dsp (void *arg)
}
if (!looping)
break;
cygwait (sleep_time >> 3);
cygwait (di->bye, sleep_time >> 3);
if (sleep_time < 80)
++sleep_time;
if (di->stop_thread)
@ -2313,6 +2316,13 @@ start_thread_dsp (select_record *me, select_stuff *stuff)
me->h = *((select_dsp_info *) stuff->device_specific_dsp)->thread;
else
{
di->bye = me->fh->get_select_sem ();
if (di->bye)
DuplicateHandle (GetCurrentProcess (), di->bye,
GetCurrentProcess (), &di->bye,
0, 0, DUPLICATE_SAME_ACCESS);
else
di->bye = CreateSemaphore (&sec_none_nih, 0, INT32_MAX, NULL);
di->start = &stuff->start;
di->stop_thread = false;
di->thread = new cygthread (thread_dsp, di, "dspsel");
@ -2324,7 +2334,7 @@ start_thread_dsp (select_record *me, select_stuff *stuff)
}
static void
dsp_cleanup (select_record *aaa, select_stuff *stuff)
dsp_cleanup (select_record *, select_stuff *stuff)
{
select_dsp_info *di = (select_dsp_info *) stuff->device_specific_dsp;
if (!di)
@ -2332,7 +2342,9 @@ dsp_cleanup (select_record *aaa, select_stuff *stuff)
if (di->thread)
{
di->stop_thread = true;
ReleaseSemaphore (di->bye, get_obj_handle_count (di->bye), NULL);
di->thread->detach ();
CloseHandle (di->bye);
}
delete di;
stuff->device_specific_dsp = NULL;