-
Notifications
You must be signed in to change notification settings - Fork 262
Make accidentally dropping OutputStream impossible #746
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
base: master
Are you sure you want to change the base?
Conversation
I agree that maintaining our own counter sucks, like in #747. But so is pulling in another dependency, kinda... it's late, but could we use Or something like this? I'm actually thinking: isn't use std::sync::Arc;
// New internal type to wrap the actual stream
struct StreamHandle {
stream: cpal::Stream,
}
pub struct OutputStream {
mixer: Mixer,
_stream: Arc<StreamHandle>,
}
impl OutputStream {
pub fn mixer(&self) -> &Mixer {
&self.mixer
}
pub fn connect_sink(&self) -> Sink {
Sink::connect_new(self.mixer())
}
} Mixer: pub struct Mixer {
_stream: Arc<StreamHandle>,
}
impl Mixer {
fn new(stream: Arc<StreamHandle>) -> Self {
Self {
_stream: stream,
}
}
fn get_stream_ref(&self) -> Arc<StreamHandle> {
self._stream.clone()
}
} Sink: pub struct Sink {
_stream: Arc<StreamHandle>,
}
impl Sink {
pub fn connect_new(mixer: &Mixer) -> Sink {
let stream_ref = mixer.get_stream_ref();
Sink {
_stream: stream_ref,
}
}
} |
Manually drop does something else, the drop bomb is crate is only a few lines so we can copy those over instead. The author is highly trusted and it made the code clean so I just added it as dependency.
If only we could, unfortunately Another issue is that its possible to drop all sinks and mixers and there should still be audio playing. Though that could probably be helped by adding a " |
Argh, what a pain. Well, if this is the lesser of evils, so be it. |
We could get #747 to work "perfectly" by moving the counter to the source. But we would have to introduce extra logic to deal with stuff like endless queue's. (We would need to track if the queue's handle has dropped and then (when the queue is empty) lower the counter). It would still be kinda ugly due to the thread that is simply there to store the Still in favor of this PR, though I really don't like making every downstream user add a custom drop implementations to whatever they are storing our |
The other option is of course to do nothing, and have users retain the stream in their struct. |
maybe there is a middle ground: We emit a warning on drop unless close is called. Its not as disrupting as a panic but it could still help out new users. |
In the case of the examples as they are today, would that mean that a warning is emitted for most of them? |
No not if we call |
OK, let's do that. |
I'll get on that tomorrow and then afterwards see if I can prep the next release |
Could it be an option to provide drop diagnostics instead? Drop may show the stack in debug mode, in lower log level settings this could be only a message mentioning the operation. |
Another alternative - to recommend keeping the output stream in a static cell, maybe? |
this is the plan now, we will print on drop unless close() was called first.
Dropping the stream before it should close is mostly an issue about not reading the docs. If you read those you will see you should not drop the stream before you are done playing sound. I do not like users having to read the docs in detail (and remember it all!). Rodio should be really easy to use. No sound (without any warning) because you dropped a variable early makes Rodio hard to use. This PR adds a crash which is impossible to miss. The proposal is to make it a warning/diagnostic. |
This adds a drop bomb to OutputStream. Dropping a OutputStream will panic (unless we are dropping as part of unwinding). Technically OutputStream is now a run time enforced linear type. To get rid of a `OutputStream` you now have to call `OutputStream::close`.
dc742f8
to
60ada81
Compare
lets remove close and the drop bomb, instead we always print something when the outputstream is dropped. We add a function to outputstream which one can use to disable the print. And we call that out from the print msg. |
This adds a drop bomb to OutputStream. Dropping a OutputStream will panic
(unless we are dropping as part of unwinding). Technically OutputStream
is now a run time enforced linear type.
To get rid of a
OutputStream
you now have to callOutputStream::close
.For a (worse in my opinion) alternative see: #747