rust-sfml icon indicating copy to clipboard operation
rust-sfml copied to clipboard

Key/Button::is_pressed are not thread safe

Open crumblingstatue opened this issue 4 years ago • 4 comments

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.

crumblingstatue avatar Sep 01 '20 16:09 crumblingstatue

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.

memoryleak47 avatar Sep 01 '20 23:09 memoryleak47

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.

crumblingstatue avatar Sep 07 '20 09:09 crumblingstatue

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 to thread::current().id() if unique_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 than thread::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() to unique_threadid)
  • add a dummy &RenderWindow argument to every non-thread safe function, which implies that this function is only called from the unique_threadid-thread.

memoryleak47 avatar Sep 07 '20 11:09 memoryleak47

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.

crumblingstatue avatar Sep 07 '20 20:09 crumblingstatue