mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-21 00:07:36 +08:00
Cygwin: dsp: Implement select()/poll().
Previously, sound device /dev/dsp did not support select()/poll(). These have been implemented with this patch. Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
This commit is contained in:
parent
7a43763d24
commit
2c06014f12
@ -1483,3 +1483,41 @@ fhandler_dev_dsp::_fixup_after_exec ()
|
|||||||
audio_out_ = NULL;
|
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 ();
|
||||||
|
}
|
||||||
|
@ -2847,6 +2847,9 @@ class fhandler_dev_dsp: public fhandler_base
|
|||||||
void close_audio_in ();
|
void close_audio_in ();
|
||||||
void close_audio_out (bool = false);
|
void close_audio_out (bool = false);
|
||||||
|
|
||||||
|
bool _read_ready();
|
||||||
|
bool _write_ready();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool use_archetype () const {return true;}
|
bool use_archetype () const {return true;}
|
||||||
|
|
||||||
@ -2866,6 +2869,14 @@ class fhandler_dev_dsp: public fhandler_base
|
|||||||
fh->copy_from (this);
|
fh->copy_from (this);
|
||||||
return fh;
|
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
|
class fhandler_virtual : public fhandler_base
|
||||||
|
@ -87,6 +87,11 @@ struct select_socket_info: public select_info
|
|||||||
select_socket_info (): select_info (), num_w4 (0), ser_num (0), w4 (NULL) {}
|
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
|
class select_stuff
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -112,6 +117,7 @@ public:
|
|||||||
select_pipe_info *device_specific_ptys;
|
select_pipe_info *device_specific_ptys;
|
||||||
select_fifo_info *device_specific_fifo;
|
select_fifo_info *device_specific_fifo;
|
||||||
select_socket_info *device_specific_socket;
|
select_socket_info *device_specific_socket;
|
||||||
|
select_dsp_info *device_specific_dsp;
|
||||||
|
|
||||||
bool test_and_set (int, fd_set *, fd_set *, fd_set *);
|
bool test_and_set (int, fd_set *, fd_set *, fd_set *);
|
||||||
int poll (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_pipe (NULL),
|
||||||
device_specific_ptys (NULL),
|
device_specific_ptys (NULL),
|
||||||
device_specific_fifo (NULL),
|
device_specific_fifo (NULL),
|
||||||
device_specific_socket (NULL)
|
device_specific_socket (NULL),
|
||||||
|
device_specific_dsp (NULL)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2255,3 +2255,133 @@ fhandler_timerfd::select_except (select_stuff *stuff)
|
|||||||
s->except_ready = false;
|
s->except_ready = false;
|
||||||
return s;
|
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;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user