Skip to content

Small fixes: uninstall target guard, signed/unsigned compare, dead link - #378

Merged
insolace merged 2 commits into
thestk:masterfrom
Muse-Kinetics:housekeeping-small-fixes
Sep 21, 2026
Merged

insolace merged 2 commits into
thestk:masterfrom
Muse-Kinetics:housekeeping-small-fixes

Conversation

@insolace

Copy link
Copy Markdown
Collaborator

Three small unrelated fixes, each closing an open issue.

#369add_custom_target(uninstall) is created unconditionally, which fails configuration when RtMidi is added as a subproject alongside another library that defines its own uninstall target. Previously tolerated; fatal as of CMake 4.1. Guarded with if(NOT TARGET ...).

#291CreateConnectedEndpointName declares int i and compares it against size_t nConnected. The nConnected half was already changed to size_t upstream; this changes i to match.

#371 — the mididev Google Groups thread referenced in WinMidiData is no longer publicly reachable (the group returns an access error). Replaced the link with what it explained, keeping the attribution.

Verified on Linux (ALSA + JACK), CMake configure and build clean. The #291 change is in CoreMIDI code, which does not compile on Linux — worth a look from someone on macOS.

- CMakeLists.txt: guard the uninstall target with if(NOT TARGET ...).
  Redefining it breaks configuration when RtMidi is added as a subproject
  alongside another library that defines its own 'uninstall' target, which
  is fatal as of CMake 4.1. Fixes thestk#369.

- RtMidi.cpp: CreateConnectedEndpointName compared 'int i' against
  'size_t nConnected'. Make i a size_t. Fixes thestk#291.

- RtMidi.cpp: the mididev Google Groups thread referenced in WinMidiData is
  no longer publicly reachable. Replace the link with what it explained,
  keeping the attribution. Fixes thestk#371.
@insolace

Copy link
Copy Markdown
Collaborator Author

Follow-up on verification: the int i -> size_t i change in CreateConnectedEndpointName() is CoreMIDI code, so it had not been compiled when this was opened. It has now been built and exercised on macOS (Clang, no warnings) against real MIDI hardware — MIDI-CI Discovery and several Property Exchange transactions, all of which go through that port-name comparison — with results byte-identical to the unpatched baseline.

The other two changes (the CMake uninstall target guard and the comment edit) were verified on Linux when this was opened.

Comment thread RtMidi.cpp Outdated
MidiInApi::MidiMessage message;
std::vector<LPMIDIHDR> sysexBuffer;
CRITICAL_SECTION _mutex; // [Patrice] see https://groups.google.com/forum/#!topic/mididev/6OUjHutMpEo
CRITICAL_SECTION _mutex; // [Patrice] protects the sysex buffer requeue in midiInputCallback

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really sure a comment like this is needed. It explains what the mutex is doing, which is obvious from just looking at where the mutex is locked and unlocked. What I was hoping for to find in the dead Google Groups link is the why: How can it be possible that this buffer is accessed from multiple threads, necessitating a mutex? This question remains unanswered.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The buffer is reachable from two threads because midiInOpen() is called with CALLBACK_FUNCTION, so WinMM invokes midiInputCallback() on a thread it owns, not on any thread the application controls. That callback requeues the sysex buffer with midiInAddBuffer(). Meanwhile MidiInWinMM::closePort() runs on the application's thread and walks the same sysexBuffer vector, calling midiInUnprepareHeader() and freeing each header. Those are the only two places the critical section is taken, and they are the two sides of the race: the driver thread requeueing a buffer that the application thread is in the middle of retiring.

midiInReset() makes it concrete. closePort() calls it while holding the lock, and it is precisely what completes pending buffers and drives the callbacks that then want the same lock. So the mutex is not protecting against two application threads, it is protecting against the driver's own callback thread arriving during teardown.

I could update the comment with something saying that midiInputCallback runs on a WinMM-owned thread and requeues these buffers while closePort retires them from the caller's thread, and this guards that overlap.

Also the surrounding code has active work: #372 fixes a deadlock on exactly this interaction, and #380 rewrites the input teardown for #376.

@insolace insolace added this to the 6.1.0 milestone Sep 21, 2026
The comment replacing the dead Google Groups link said what the mutex
protects, which is visible from where it is locked. It did not answer the
question the link was supposed to answer: how the buffer is reachable from
two threads in the first place.
@insolace

Copy link
Copy Markdown
Collaborator Author

Updated the comment, onward and upward.

@insolace insolace closed this Sep 21, 2026
@insolace insolace reopened this Sep 21, 2026
@insolace
insolace merged commit 78898c0 into thestk:master Sep 21, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants