diff options
Diffstat (limited to 'winsup/cygwin')
-rw-r--r-- | winsup/cygwin/fhandler/dsp.cc | 38 | ||||
-rw-r--r-- | winsup/cygwin/local_includes/fhandler.h | 11 | ||||
-rw-r--r-- | winsup/cygwin/local_includes/select.h | 9 | ||||
-rw-r--r-- | winsup/cygwin/select.cc | 130 |
4 files changed, 187 insertions, 1 deletions
diff --git a/winsup/cygwin/fhandler/dsp.cc b/winsup/cygwin/fhandler/dsp.cc index 8614433..f1634f7 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_ = 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 f2658a2..d7dc02e 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 = false); + bool _read_ready(); + bool _write_ready(); + public: bool use_archetype () const {return true;} @@ -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(); }; class fhandler_virtual : public fhandler_base diff --git a/winsup/cygwin/local_includes/select.h b/winsup/cygwin/local_includes/select.h index b794690..4e20212 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) {} }; +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; 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) {} }; diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index bad4c37..3ad12c2 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -2255,3 +2255,133 @@ fhandler_timerfd::select_except (select_stuff *stuff) s->except_ready = false; return s; } + +static int +peek_dsp (select_record *s, bool from_select) +{ + int gotone = 0; + fhandler_dev_dsp *fh = (fhandler_dev_dsp *)(fhandler_base *) s->fh; + + if (s->read_selected) + if (s->read_ready || fh->read_ready ()) + gotone += s->read_ready = true; + if (s->write_selected) + if (s->write_ready || fh->write_ready ()) + gotone += s->write_ready = true; + return gotone; +} + +static int start_thread_dsp (select_record *me, select_stuff *stuff); + +static DWORD +thread_dsp (void *arg) +{ + select_dsp_info *di = (select_dsp_info *) arg; + DWORD sleep_time = 0; + bool looping = true; + + while (looping) + { + for (select_record *s = di->start; (s = s->next); ) + if (s->startup == start_thread_dsp) + { + if (peek_dsp (s, true)) + looping = false; + if (di->stop_thread) + { + select_printf ("stopping"); + looping = 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 = stuff->device_specific_dsp; + if (di->start) + me->h = *((select_dsp_info *) stuff->device_specific_dsp)->thread; + else + { + di->start = &stuff->start; + di->stop_thread = false; + di->thread = new cygthread (thread_dsp, di, "dspsel"); + me->h = *di->thread; + if (!me->h) + return 0; + } + return 1; +} + +static void +dsp_cleanup (select_record *aaa, select_stuff *stuff) +{ + select_dsp_info *di = (select_dsp_info *) stuff->device_specific_dsp; + if (!di) + return; + if (di->thread) + { + di->stop_thread = true; + di->thread->detach (); + } + delete di; + stuff->device_specific_dsp = NULL; +} + +select_record * +fhandler_dev_dsp::select_read (select_stuff *stuff) +{ + if (!stuff->device_specific_dsp + && (stuff->device_specific_dsp = new select_dsp_info) == NULL) + return NULL; + select_record *s = stuff->start.next; + s->startup = start_thread_dsp; + s->peek = peek_dsp; + s->verify = verify_ok; + s->cleanup = dsp_cleanup; + s->read_selected = true; + s->read_ready = false; + return s; +} + +select_record * +fhandler_dev_dsp::select_write (select_stuff *stuff) +{ + if (!stuff->device_specific_dsp + && (stuff->device_specific_dsp = new select_dsp_info) == NULL) + return NULL; + select_record *s = stuff->start.next; + s->startup = start_thread_dsp; + s->peek = peek_dsp; + s->verify = verify_ok; + s->cleanup = dsp_cleanup; + s->write_selected = true; + s->write_ready = false; + return s; +} + +select_record * +fhandler_dev_dsp::select_except (select_stuff *stuff) +{ + if (!stuff->device_specific_dsp + && (stuff->device_specific_dsp = new select_dsp_info) == NULL) + return NULL; + select_record *s = stuff->start.next; + s->startup = start_thread_dsp; + s->peek = peek_dsp; + s->verify = verify_ok; + s->cleanup = dsp_cleanup; + s->except_selected = true; + s->except_ready = false; + return s; +} |