Add the necessary locking to the sndio MIDI backend

Fixes crashes caused concurrent accesses to the sndio MIDI handle.

ok rsadowski
This commit is contained in:
ratchov
2026-05-25 14:40:36 +00:00
parent 92f30a990c
commit 60dcac9ba9
3 changed files with 81 additions and 1 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ DISTNAME = lmms_$V
PKGNAME = lmms-$V
WRKDIST = ${WRKDIR}/lmms
EXTRACT_SUFX = .tar.xz
REVISION = 1
REVISION = 2
CATEGORIES = audio
@@ -0,0 +1,19 @@
Index: include/MidiSndio.h
--- include/MidiSndio.h.orig
+++ include/MidiSndio.h
@@ -32,6 +32,7 @@
#include <QtCore/QThread>
#include <QtCore/QFile>
+#include <QtCore/QMutex>
#include <sndio.h>
@@ -64,6 +65,7 @@ class MidiSndio : public MidiClientRaw, public QThread
virtual void run(void);
private:
+ QMutex m_hdlMutex;
struct mio_hdl *m_hdl;
volatile bool m_quit;
} ;
@@ -0,0 +1,61 @@
Index: src/core/midi/MidiSndio.cpp
--- src/core/midi/MidiSndio.cpp.orig
+++ src/core/midi/MidiSndio.cpp
@@ -42,6 +42,7 @@
MidiSndio::MidiSndio( void ) :
MidiClientRaw(),
+ m_hdlMutex(),
m_quit( false )
{
QString dev = probeDevice();
@@ -86,7 +87,9 @@ QString MidiSndio::probeDevice( void )
void MidiSndio::sendByte( const unsigned char c )
{
+ m_hdlMutex.lock();
mio_write( m_hdl, &c, 1 );
+ m_hdlMutex.unlock();
}
@@ -96,20 +99,33 @@ void MidiSndio::run( void )
nfds_t nfds;
char buf[0x100], *p;
size_t n;
+ int revents;
int ret;
+
while( m_quit == false && m_hdl )
{
+ m_hdlMutex.lock();
nfds = mio_pollfd( m_hdl, &pfd, POLLIN );
+ m_hdlMutex.unlock();
ret = poll( &pfd, nfds, 100 );
- if ( ret < 0 )
+ if ( ret < 0 ) {
+ if (errno == EINTR)
+ continue;
+ fprintf(stderr, "sndio: poll: %s\n", strerror(errno));
break;
- if ( !ret || !( mio_revents( m_hdl, &pfd ) & POLLIN ) )
- continue;
- n = mio_read( m_hdl, buf, sizeof(buf) );
- if ( !n )
- {
+ }
+ m_hdlMutex.lock();
+ revents = mio_revents( m_hdl, &pfd );
+ if (revents & POLLHUP) {
+ fprintf(stderr, "sndio: device disconnected\n");
+ m_hdlMutex.unlock();
break;
}
+ if (revents & POLLIN) {
+ n = mio_read( m_hdl, buf, sizeof(buf) );
+ } else
+ n = 0;
+ m_hdlMutex.unlock();
for (p = buf; n > 0; n--, p++)
{
parseData( *p );