OSS: Improvements to blocking waiting logic.

This now does a single select() rather than two separate ones for
capture and playback. This should make duplex mode better.
This commit is contained in:
David Reid
2026-01-14 07:36:41 +10:00
parent 3277d995a3
commit bdde9c46b0
+29 -28
View File
@@ -39701,8 +39701,11 @@ static ma_result ma_device_step__oss(ma_device* pDevice, ma_blocking_mode blocki
ma_device_type deviceType = ma_device_get_type(pDevice); ma_device_type deviceType = ma_device_get_type(pDevice);
struct timeval tv; struct timeval tv;
struct timeval* pTimeout = NULL; struct timeval* pTimeout = NULL;
fd_set fds; fd_set fdsRead;
fd_set fdsWrite;
int fdMax;
ma_result result; ma_result result;
int selectResult;
if (blockingMode == MA_BLOCKING_MODE_NON_BLOCKING) { if (blockingMode == MA_BLOCKING_MODE_NON_BLOCKING) {
tv.tv_sec = 0; tv.tv_sec = 0;
@@ -39710,22 +39713,34 @@ static ma_result ma_device_step__oss(ma_device* pDevice, ma_blocking_mode blocki
pTimeout = &tv; pTimeout = &tv;
} }
if (deviceType == ma_device_type_capture || deviceType == ma_device_type_duplex) { do
int retval; {
FD_ZERO(&fdsRead);
FD_ZERO(&fdsWrite);
do fdMax = 0;
{
FD_ZERO(&fds);
FD_SET(pDeviceStateOSS->fdCapture, &fds);
retval = select(pDeviceStateOSS->fdCapture + 1, &fds, NULL, NULL, pTimeout); if (deviceType == ma_device_type_capture || deviceType == ma_device_type_duplex) {
} while (retval < 0 && errno == EINTR); FD_SET(pDeviceStateOSS->fdCapture, &fdsRead);
fdMax = ma_max(fdMax, pDeviceStateOSS->fdCapture);
if (!ma_device_is_started(pDevice)) { }
return MA_DEVICE_NOT_STARTED;
if (deviceType == ma_device_type_playback || deviceType == ma_device_type_duplex) {
FD_SET(pDeviceStateOSS->fdPlayback, &fdsWrite);
fdMax = ma_max(fdMax, pDeviceStateOSS->fdPlayback);
} }
if (FD_ISSET(pDeviceStateOSS->fdCapture, &fds)) { selectResult = select(fdMax + 1, &fdsRead, &fdsWrite, NULL, pTimeout);
} while (selectResult < 0 && errno == EINTR);
if (!ma_device_is_started(pDevice)) {
return MA_DEVICE_NOT_STARTED;
}
if (deviceType == ma_device_type_capture || deviceType == ma_device_type_duplex) {
if (FD_ISSET(pDeviceStateOSS->fdCapture, &fdsRead)) {
ma_uint32 framesRead; ma_uint32 framesRead;
result = ma_device_read__oss(pDevice, pDeviceStateOSS->pIntermediaryBufferCapture, pDevice->capture.internalPeriodSizeInFrames, &framesRead); result = ma_device_read__oss(pDevice, pDeviceStateOSS->pIntermediaryBufferCapture, pDevice->capture.internalPeriodSizeInFrames, &framesRead);
@@ -39738,21 +39753,7 @@ static ma_result ma_device_step__oss(ma_device* pDevice, ma_blocking_mode blocki
} }
if (deviceType == ma_device_type_playback || deviceType == ma_device_type_duplex) { if (deviceType == ma_device_type_playback || deviceType == ma_device_type_duplex) {
int retval; if (FD_ISSET(pDeviceStateOSS->fdPlayback, &fdsWrite)) {
do
{
FD_ZERO(&fds);
FD_SET(pDeviceStateOSS->fdPlayback, &fds);
retval = select(pDeviceStateOSS->fdPlayback + 1, NULL, &fds, NULL, pTimeout);
} while (retval < 0 && errno == EINTR);
if (!ma_device_is_started(pDevice)) {
return MA_DEVICE_NOT_STARTED;
}
if (FD_ISSET(pDeviceStateOSS->fdPlayback, &fds)) {
ma_uint32 framesWritten; ma_uint32 framesWritten;
result = ma_device_write__oss(pDevice, pDeviceStateOSS->pIntermediaryBufferPlayback, pDevice->playback.internalPeriodSizeInFrames, &framesWritten); result = ma_device_write__oss(pDevice, pDeviceStateOSS->pIntermediaryBufferPlayback, pDevice->playback.internalPeriodSizeInFrames, &framesWritten);