Skip to content
Snippets Groups Projects
Commit 90d0ca1a authored by Stan Seibert's avatar Stan Seibert
Browse files

Compromise on the blocking open() call with certain OSS drivers. The

workaround is now turned off by default.  If the --enable-broken-oss
option is passed to configure or if ALSA is detected, the workaround is
turned on during compilation.  This will resolve bug 48.


git-svn-id: http://svn.xiph.org/trunk/ao@2146 0101bb08-14d6-0310-b084-bc0e0c8e3800
parent 3b0705a0
No related branches found
No related tags found
No related merge requests found
......@@ -51,3 +51,15 @@ could be provided. The API was revised for version 0.8.0.
This code is being maintained by Stan Seibert (indigo@aztec.asu.edu)
and various other individuals. Please DO NOT annoy Aaron Holtzman about
bugs, features, comments, etc. regarding this code.
WORKAROUNDS
The OSS emulation in ALSA deviates from the OSS spec by not returning
immediately from an open() call if the OSS device is already in use.
Instead, it makes the application wait until the device is available.
This is not desirable during the autodetection phase of libao, so a
workaround has been included in the source. Since the workaround
itself violates the OSS spec and causes other problems on some
platforms, it is only enabled when ALSA is detected. The workaround
can be turned on or off by passing the --enable-broken-oss or
--disable-broken-oss flag to the configure script.
......@@ -196,7 +196,19 @@ else
fi
AC_SUBST(ALSA09_LIBS)
dnl Decide whether we need to enable the workaround for broken OSS APIs
dnl such as the OSS emulation in ALSA.
AC_ARG_ENABLE(broken-oss, [ --enable-broken-oss workaround for some OSS drivers (see README for details)],,
if test "x$have_alsa" = "xyes" -o "x$have_alsa09" = "xyes"; then
enable_broken_oss="yes"
fi)
if test "x$enable_broken_oss" = "xyes"; then
AC_DEFINE(BROKEN_OSS)
AC_MSG_WARN(Broken OSS API workaround enabled. See README for details.)
fi
dnl Check for Sun audio
AC_CHECK_HEADERS(sys/audioio.h)
......
......@@ -70,10 +70,11 @@ typedef struct ao_oss_internal {
* *dev_path. Assumes that *dev_path does not need to be free()'ed
* initially.
*
* This opens the device in non-blocking mode at first in order to prevent
* deadlock caused by ALSA's OSS emulation and some OSS drivers if the
* device is already in use. If blocking is non-zero, we remove the blocking
* flag if possible so that the device can be used for actual output.
* If BROKEN_OSS is defined, this opens the device in non-blocking
* mode at first in order to prevent deadlock caused by ALSA's OSS
* emulation and some OSS drivers if the device is already in use. If
* blocking is non-zero, we remove the blocking flag if possible so
* that the device can be used for actual output.
*/
int _open_default_oss_device (char **dev_path, int blocking)
{
......@@ -83,7 +84,11 @@ int _open_default_oss_device (char **dev_path, int blocking)
/* default: first try the devfs path */
*dev_path = strdup("/dev/sound/dsp");
#ifdef BROKEN_OSS
fd = open(*dev_path, O_WRONLY | O_NONBLOCK);
#else
fd = open(*dev_path, O_WRONLY);
#endif /* BROKEN_OSS */
/* then try the original dsp path */
if(fd < 0)
......@@ -93,9 +98,14 @@ int _open_default_oss_device (char **dev_path, int blocking)
dev = strdup(*dev_path);
free(*dev_path);
*dev_path = strdup("/dev/dsp");
#ifdef BROKEN_OSS
fd = open(*dev_path, O_WRONLY | O_NONBLOCK);
#else
fd = open(*dev_path, O_WRONLY);
#endif /* BROKEN_OSS */
}
#ifdef BROKEN_OSS
/* Now have to remove the O_NONBLOCK flag if so instructed. */
if (fd > 0 && blocking) {
if (fcntl(fd, F_SETFL, 0) < 0) { /* Remove O_NONBLOCK */
......@@ -105,6 +115,7 @@ int _open_default_oss_device (char **dev_path, int blocking)
fd = -1;
}
}
#endif /* BROKEN_OSS */
/* Deal with error cases */
if(fd < 0)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment