From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7868) id C30303858401; Wed, 6 Sep 2023 15:21:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C30303858401 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1694013714; bh=Wm+ElPAJspCzWZnXkjMA2gxMI54UlxRzsMP4x05SPds=; h=From:To:Subject:Date:From; b=heQGVQUMq+1+vRfNqS9AKDby3EPX+lwAbIKlrVyAHtSbTtdlo276XpOyQ5u1Ix3ud xgMwM6aiaWKkiewfhn6q6TKmJUVBpqE+VbFpDfhG7/0y2olgk7VntSO3CIX00NV1kG jZxOIYJ3pkFXI7jv59VNNVpujbMYV7KNXyOLQ6iE= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Takashi Yano To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin] Cygwin: dsp: Implement select()/poll(). X-Act-Checkin: newlib-cygwin X-Git-Author: Takashi Yano X-Git-Refname: refs/heads/master X-Git-Oldrev: 7a43763d24ab693502b0d0b1323d8cba1123e59a X-Git-Newrev: 2c06014f12b0231e40d4256ae5f0d16a4b21be48 Message-Id: <20230906152154.C30303858401@sourceware.org> Date: Wed, 6 Sep 2023 15:21:54 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3D2c06014f12b= 0231e40d4256ae5f0d16a4b21be48 commit 2c06014f12b0231e40d4256ae5f0d16a4b21be48 Author: Takashi Yano Date: Wed Sep 6 22:03:18 2023 +0900 Cygwin: dsp: Implement select()/poll(). =20 Previously, sound device /dev/dsp did not support select()/poll(). These have been implemented with this patch. =20 Signed-off-by: Takashi Yano Diff: --- winsup/cygwin/fhandler/dsp.cc | 38 ++++++++++ winsup/cygwin/local_includes/fhandler.h | 11 +++ winsup/cygwin/local_includes/select.h | 9 ++- winsup/cygwin/select.cc | 130 ++++++++++++++++++++++++++++= ++++ 4 files changed, 187 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/fhandler/dsp.cc b/winsup/cygwin/fhandler/dsp.cc index 861443352..f1634f7a8 100644 --- a/winsup/cygwin/fhandler/dsp.cc +++ b/winsup/cygwin/fhandler/dsp.cc @@ -1483,3 +1483,41 @@ fhandler_dev_dsp::_fixup_after_exec () audio_out_ =3D NULL; } } + +bool +fhandler_dev_dsp::_write_ready () +{ + audio_buf_info info; + if (audio_out_) + { + audio_out_->buf_info (&info, audiofreq_, audiobits_, audiochannels_); + return info.bytes > 0; + } + else + return true; +} + +bool +fhandler_dev_dsp::_read_ready () +{ + audio_buf_info info; + if (audio_in_) + { + audio_in_->buf_info (&info, audiofreq_, audiobits_, audiochannels_); + return info.bytes > 0; + } + else + return true; +} + +bool +fhandler_dev_dsp::write_ready () +{ + return base ()->_write_ready (); +} + +bool +fhandler_dev_dsp::read_ready () +{ + return base ()->_read_ready (); +} diff --git a/winsup/cygwin/local_includes/fhandler.h b/winsup/cygwin/local_= includes/fhandler.h index f2658a242..d7dc02e89 100644 --- a/winsup/cygwin/local_includes/fhandler.h +++ b/winsup/cygwin/local_includes/fhandler.h @@ -2847,6 +2847,9 @@ class fhandler_dev_dsp: public fhandler_base void close_audio_in (); void close_audio_out (bool =3D false); =20 + bool _read_ready(); + bool _write_ready(); + public: bool use_archetype () const {return true;} =20 @@ -2866,6 +2869,14 @@ class fhandler_dev_dsp: public fhandler_base fh->copy_from (this); return fh; } + + /* select.cc */ + select_record *select_read (select_stuff *); + select_record *select_write (select_stuff *); + select_record *select_except (select_stuff *); + + bool read_ready(); + bool write_ready(); }; =20 class fhandler_virtual : public fhandler_base diff --git a/winsup/cygwin/local_includes/select.h b/winsup/cygwin/local_in= cludes/select.h index b794690b6..4e202128f 100644 --- a/winsup/cygwin/local_includes/select.h +++ b/winsup/cygwin/local_includes/select.h @@ -87,6 +87,11 @@ struct select_socket_info: public select_info select_socket_info (): select_info (), num_w4 (0), ser_num (0), w4 (NULL= ) {} }; =20 +struct select_dsp_info: public select_info +{ + select_dsp_info (): select_info () {} +}; + class select_stuff { public: @@ -112,6 +117,7 @@ public: select_pipe_info *device_specific_ptys; select_fifo_info *device_specific_fifo; select_socket_info *device_specific_socket; + select_dsp_info *device_specific_dsp; =20 bool test_and_set (int, fd_set *, fd_set *, fd_set *); int poll (fd_set *, fd_set *, fd_set *); @@ -125,7 +131,8 @@ public: device_specific_pipe (NULL), device_specific_ptys (NULL), device_specific_fifo (NULL), - device_specific_socket (NULL) + device_specific_socket (NULL), + device_specific_dsp (NULL) {} }; =20 diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index bad4c37f3..3ad12c262 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -2255,3 +2255,133 @@ fhandler_timerfd::select_except (select_stuff *stuf= f) s->except_ready =3D false; return s; } + +static int +peek_dsp (select_record *s, bool from_select) +{ + int gotone =3D 0; + fhandler_dev_dsp *fh =3D (fhandler_dev_dsp *)(fhandler_base *) s->fh; + + if (s->read_selected) + if (s->read_ready || fh->read_ready ()) + gotone +=3D s->read_ready =3D true; + if (s->write_selected) + if (s->write_ready || fh->write_ready ()) + gotone +=3D s->write_ready =3D true; + return gotone; +} + +static int start_thread_dsp (select_record *me, select_stuff *stuff); + +static DWORD +thread_dsp (void *arg) +{ + select_dsp_info *di =3D (select_dsp_info *) arg; + DWORD sleep_time =3D 0; + bool looping =3D true; + + while (looping) + { + for (select_record *s =3D di->start; (s =3D s->next); ) + if (s->startup =3D=3D start_thread_dsp) + { + if (peek_dsp (s, true)) + looping =3D false; + if (di->stop_thread) + { + select_printf ("stopping"); + looping =3D false; + break; + } + } + if (!looping) + break; + cygwait (sleep_time >> 3); + if (sleep_time < 80) + ++sleep_time; + if (di->stop_thread) + break; + } + return 0; +} + +static int +start_thread_dsp (select_record *me, select_stuff *stuff) +{ + select_dsp_info *di =3D stuff->device_specific_dsp; + if (di->start) + me->h =3D *((select_dsp_info *) stuff->device_specific_dsp)->thread; + else + { + di->start =3D &stuff->start; + di->stop_thread =3D false; + di->thread =3D new cygthread (thread_dsp, di, "dspsel"); + me->h =3D *di->thread; + if (!me->h) + return 0; + } + return 1; +} + +static void +dsp_cleanup (select_record *aaa, select_stuff *stuff) +{ + select_dsp_info *di =3D (select_dsp_info *) stuff->device_specific_dsp; + if (!di) + return; + if (di->thread) + { + di->stop_thread =3D true; + di->thread->detach (); + } + delete di; + stuff->device_specific_dsp =3D NULL; +} + +select_record * +fhandler_dev_dsp::select_read (select_stuff *stuff) +{ + if (!stuff->device_specific_dsp + && (stuff->device_specific_dsp =3D new select_dsp_info) =3D=3D NULL) + return NULL; + select_record *s =3D stuff->start.next; + s->startup =3D start_thread_dsp; + s->peek =3D peek_dsp; + s->verify =3D verify_ok; + s->cleanup =3D dsp_cleanup; + s->read_selected =3D true; + s->read_ready =3D false; + return s; +} + +select_record * +fhandler_dev_dsp::select_write (select_stuff *stuff) +{ + if (!stuff->device_specific_dsp + && (stuff->device_specific_dsp =3D new select_dsp_info) =3D=3D NULL) + return NULL; + select_record *s =3D stuff->start.next; + s->startup =3D start_thread_dsp; + s->peek =3D peek_dsp; + s->verify =3D verify_ok; + s->cleanup =3D dsp_cleanup; + s->write_selected =3D true; + s->write_ready =3D false; + return s; +} + +select_record * +fhandler_dev_dsp::select_except (select_stuff *stuff) +{ + if (!stuff->device_specific_dsp + && (stuff->device_specific_dsp =3D new select_dsp_info) =3D=3D NULL) + return NULL; + select_record *s =3D stuff->start.next; + s->startup =3D start_thread_dsp; + s->peek =3D peek_dsp; + s->verify =3D verify_ok; + s->cleanup =3D dsp_cleanup; + s->except_selected =3D true; + s->except_ready =3D false; + return s; +}