rust-sfml
rust-sfml copied to clipboard
Key/Button::is_pressed are not thread safe
At least on X11, it can trigger all kinds of errors to call them from a different thread. And someone messaged me that it can cause segfaults for them to do so.
One partial solution to this would to add a dummy &RenderWindow parameter to Key::is_pressed. This should prevent it from being called in another thread than where the RenderWindow lives, because RenderWindow is !Sync.
This wouldn't work whenever the user creates multiple RenderWindows though.
Looks like is_pressed isn't the only misbehaving API. There can be threading related errors for example if you create 2 sf::RenderWindows on 2 different threads. And there is probably more.
I don't have any clear plan on how to solve all of these threading issues, so for the time being I just added a warning to the documentation.
What about adding a static unique_threadid: OnceCell<ThreadId>
containing the thread id of the thread in which a RenderWindow is spawned.
And in RenderWindow::new()
one
- sets
unique_threadid
tothread::current().id()
ifunique_threadid.get().is_none()
- does nothing if
unique_threadid.get() == Some(thread::current().id())
- returns an error / panics, if the
unique_threadid.get().is_some()
but contains another thread-id thanthread::current().id()
.
Using this, every RenderWindow has to live in the same thread.
This then allows to either:
- let non-thread-safe functions panic / error if they are called from the wrong thread (by comparing
thread::current().id()
tounique_threadid
) - add a dummy
&RenderWindow
argument to every non-thread safe function, which implies that this function is only called from theunique_threadid
-thread.
That sounds like it might work. If you'd like you can submit a pull request, but for now I'll try to explore what other thread safety issues we might have.