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

Audio thread safety, improve AudioCVT #312

Merged
merged 5 commits into from
Feb 2, 2015
Merged

Conversation

nukep
Copy link
Contributor

@nukep nukep commented Jan 31, 2015

The AudioCallback trait must implement Send.
Send declares that the audio callback data is safe to be sent across other threads (i.e. the audio callback thread).

As a result, types that can only be used on a single thread, such as Rc<T>, raw pointers and even our own Renderer, cannot be sent.

As long as the struct implementing AudioCallback does not include any non-Sendable fields, user code should compile without explicitly having to declare Send. Notice the audio-whitenoise example didn't change at all.

The only drawback is that Send imposes a 'static lifetime. That means no (non-static) references are allowed to be stored in the audio callback. However, the restriction should (hopefully) be lifted soon with rust-lang/rfcs#458.


Changes to AudioCVT are fairly simple. Because I'm getting lazy and don't want to write more things, you can just read the commit messages if you want more details. :D

nukep added 5 commits January 31, 2015 07:32
The size of SDL_AudioCVT is known at compile-time, so no heap
allocation is necessary.

convert() can only fail if buf is NULL, which, in this case, it never
can be. Additionally, the function can still succeed if no conversion
is needed; just do nothing to the buffer!

AudioCVT.len unfortunately uses an int and not a size_t,
so an overflow check is added to make sure the buffer length
is within c_int.
These methods can help the user improve performance.

* is_conversion_needed() can be used to decide if convert() needs to
  be called. If not, the user can decide to omit the call.
* get_capacity() can be used to avoid vector reallocations that are
  possible in the convert() method.
Because the audio callback data is used by an audio thread, we should
declare that said data can be transferred to other threads.

The trait does not implement Sync; the data is not accessed
concurrently by many threads.
std::sync::MutexGuard does the same thing.
Classically, mutexes cannot be unlocked from another thread.

`!Send` is a negative trait, and thus requires us to ungate the
`optin_builtin_traits` feature.
@AngryLawyer
Copy link
Member

Great stuff! Cheers

AngryLawyer added a commit that referenced this pull request Feb 2, 2015
Audio thread safety, improve AudioCVT
@AngryLawyer AngryLawyer merged commit ffb1d8e into Rust-SDL2:master Feb 2, 2015
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

Successfully merging this pull request may close these issues.

2 participants