Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add example for multithread #70

Open
hughrawlinson opened this issue Sep 8, 2020 · 4 comments
Open

Add example for multithread #70

hughrawlinson opened this issue Sep 8, 2020 · 4 comments

Comments

@hughrawlinson
Copy link
Contributor

Hi! I'm having a hard time using midir in a threaded context. I'm using threads to model polyphony, as is typical in many synth implementations I've seen. I specifically don't know what is safe to share using Arc/Mutex. If nothing, I'm not sure how to be confident that I spin up a connection to the same port on a new thread. It looks like I can't share MidiOutputPorts between different instances of MidiOutput.

Or is it better to not use threading at all, and just keep a single thread, and handle scheduling of events?

Thanks for any insight!

@Woyten
Copy link

Woyten commented Oct 23, 2020

I specifically don't know what is safe to share using Arc/Mutex.

@hughrawlinson You should not need to worry about that. If your multi-threaded code compiles (and doesn't make use of unsafe), it is guaranteed by the library to be safe.

If you have problems getting your code to compile in multiple threads you can use the following strategy:

  • If an operation on an object consumes &self and the object is Sync wrap your object it in an Arc<_>.
  • If an operation on an object consumes &mut self or the object isn't Sync wrap your object in an Arc<Mutex<_>>

As a reference you can check out my synthesizer project https://crates.io/crates/microwave.

@Boddlnagg
Copy link
Owner

Is there any question still open? Otherwise I'd close this issue.

@hughrawlinson
Copy link
Contributor Author

Thanks for getting back to me. That clarifies things a bit - although, I'm not sure exactly what the library guarantees to be safe. One remaining question is:

If I get a MidiOutputPort on the main thread, and pass it into another thread in the manner you described, and then I unplug the midi device, does that reference break somehow? If so, how do I catch that? Or is that not the kind of guarantee that the library makes?

I also think it would be good to have an example of this - either a specific contrived example like the other examples, or perhaps a link out to the crate you mentioned?

Thanks! 😄

@avindra
Copy link

avindra commented Dec 1, 2020

If I get a MidiOutputPort on the main thread, and pass it into another thread in the manner you described, and then ....

@hughrawlinson yeah, you should be able to safely run it on another thread and pass the messages somewhere else. I did a small example of this with tungstenite-rs server: snapview/tungstenite-rs#122 (comment) . I am more familiar with functional languages than traditional systems programming, so if you have that background too it might help.

To be more specific I am shoveling the midi messages from midir to tungstenite, and everything works smoothly, no crashes etc. It uses all of 4MB of RAM when it's running and I'm just testing locally.

If I unplug the midi device, does that reference break somehow?

It's not currently possible to detect disconnected devices. In theory this can be added (at least on Linux). See #35 for more on unplugging the device.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants