-
Notifications
You must be signed in to change notification settings - Fork 468
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
Thread Safety: EventSubsystem and TimerSubsystem violate Sync
, allows using an Sdl
context from multiple threads.
#1063
Comments
Upgrading from Rc to Arc is better, but as far as I understand SDL2 the events system in particular is not send and in general SDL2 is absolutely not thread safe. The only part of the API that's documented as thread safe is Audio. Video/Events is absolutely not thread safe.
|
some event and timer function SDL2 says are explicitly thread safe. The issue is the thread-unsafe refcounting (upgrade to Arc), and (supposedly) thread-safe subsystems exposing the definitely not thread-safe Sdl context. |
for testing I wrote a quick gist that roughly mocks the sdl2-rs API, but thread-safely. |
following some further discussion with @Lokathor I think I'd rather be in favour of the |
Sync
, allow using an Sdl
context from multiple threads.Sync
, allows using an Sdl
context from multiple threads.
Its possible to remove the |
|
Thanks for pointing this out. I had heard about scoped threads while preparing this issue but presumed them to be a nightly feature rather than from a external crate. Either way I hope my initial example shows the bug definitely lies with rust-sdl2, and not any other dependencies of mine
I believe I tried 1. but Box is only Send or Sync if its contents are, so you specifically need to pass a shared reference to the subsystem. I may be misunderstanding though, if you can provide a better example that would be appreciated. |
Ah, right. You are correct. Boxes are only Send when the content is. Sorry, I misunderstood where the box was being talked about. Honestly I'm not the most familiar with |
According to sdl.rs, the event and timer subsystems can be safely accessed from multiple threads. For this reason, they
unsafe impl Sync
.The Rust standard library defines
Sync
as such:This is an important invariant that must be upheld for
unsafe impl Sync
to be sound. However, subsystems contain anRc<SubsystemDrop>
. Rust makes it very clear thatRc
is not Send:This allows us to pass a
&TimerSubsystem
between threads. From there, we couldclone
it, and cause a race on the containedRc
s changing their reference count, or obtain a handle to the mainSdl
context, and access other, not thread-safe subsystems.Here is an example demonstrating the latter:
One fix for this would be to simply make all subsystems
nosync
, as the current structure does not allow any way for this to be sound. Additionally, withoutSend
, we have to have a&'static Subsystem
to even use these subsystems from another thread, which means proper deinitialization viaSDL_QuitSubsystem
orSDL_Quit
cannot occur.Alternatively, although I have not tested this yet, using
Arc
forSdl
, opting out ofSend
andSync
, and also usingArc
forEventSubsystem
andThreadSubsystem
may be enough to fix things.The text was updated successfully, but these errors were encountered: