On Fri, Apr 25, 2025 at 05:32:33PM -0500, izzy Meyer wrote:
> On Thu, 24 Apr 2025 15:33:18 +0200
> Alexandre Ratchov <[email protected]> wrote:
> 
> > MIDI output and input are handled on different threads, so a mutex is
> > required to serialize access to the mio_hdl structure.
> > 
> > This diff fixes disconnection from sndiod caused by corruption of the
> > mio_hdl structure.
> > 
> > While we're at it, fix the input event loop to not stop if a signal is
> > received during poll(4). If so just recheck the m_quit flag and retry.
> > 
> > OK?
> > 
> 
> Thanks for this fix Alexandre. I produce on OpenBSD using LMMS. Tested
> on amd64. Seems good from some minimal testing on my production
> machine.
> 

I don't remember why, but this diff was forgotten. Here's a refreshed
version, with better error handling.

OK?

Index: Makefile
===================================================================
RCS file: /cvs/ports/audio/lmms/Makefile,v
diff -u -p -u -p -r1.29 Makefile
--- Makefile    13 Feb 2026 12:02:13 -0000      1.29
+++ Makefile    25 May 2026 12:34:20 -0000
@@ -5,7 +5,7 @@ DISTNAME =              lmms_$V
 PKGNAME =              lmms-$V
 WRKDIST =              ${WRKDIR}/lmms
 EXTRACT_SUFX =         .tar.xz
-REVISION =             1
+REVISION =             2
 
 CATEGORIES =           audio
 
Index: patches/patch-include_MidiSndio_h
===================================================================
RCS file: patches/patch-include_MidiSndio_h
diff -N patches/patch-include_MidiSndio_h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-include_MidiSndio_h   25 May 2026 12:34:20 -0000
@@ -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;
+ } ;
Index: patches/patch-src_core_midi_MidiSndio_cpp
===================================================================
RCS file: patches/patch-src_core_midi_MidiSndio_cpp
diff -N patches/patch-src_core_midi_MidiSndio_cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-src_core_midi_MidiSndio_cpp   25 May 2026 12:34:20 -0000
@@ -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 );

Reply via email to