-
Notifications
You must be signed in to change notification settings - Fork 902
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
On Windows, only return the window handle if it is on the correct thread #3593
Conversation
Confirmed to operate as intended on windows |
How does it behave with e.g. EGL where windows are |
src/platform_impl/windows/window.rs
Outdated
@@ -382,6 +382,12 @@ impl Window { | |||
#[cfg(feature = "rwh_06")] | |||
#[inline] | |||
pub fn raw_window_handle_rwh_06(&self) -> Result<rwh_06::RawWindowHandle, rwh_06::HandleError> { | |||
// If we aren't in the GUI thread, we can't return the window. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should link to docs on why it's like that.
fn issue_3593() { | ||
// We should not be able to get a window handle off of the main thread. | ||
let event_loop = EventLoop::new().unwrap(); | ||
event_loop.run(|_, elwt| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't use deprecated API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a better way to create a closure application ad-hoc?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really, no. This would have to be done with ApplicationHandler
:
struct App;
impl ApplicationHandler for App {
fn new_events(&mut self, event_loop: &ActiveEventLoop, _cause: StartCause) {
// Test code in here
}
}
fn issue_3593() {
let event_loop = EventLoop::new().unwrap();
event_loop.run_app(App).unwrap();
}
I guess for the purpose of integration tests, we should probably have some sort of mechanism to do this more easily.
Is there a reference for this somewhere? |
Generally windows are thread unsafe unless otherwise specified. For instance, Raymond Chen says:
So From the
I'm saying that the definition of "valid" is "valid for the current context." As |
CC rust-windowing/raw-window-handle#154 and rust-windowing/raw-window-handle#85 (comment), talk about making |
I'd really like some confirmation from |
@Stehfyn Can you comment here? |
I can see |
I mean how OpenGL/Vulkan then operate where every surface resource is |
This commit clarifies what is expected by the system for a Win32 handle. It is expected that the Win32 handle belongs to the current thread. This is not a breaking change as it was previously necessary for the window to be considered "valid". cc rust-windowing/winit#3593 Signed-off-by: John Nunley <dev@notgull.net>
I've added a couple of escape hatches to allow for thread-safe usage. However for the default usage we should account for thread affinity |
This commit clarifies what is expected by the system for a Win32 handle. It is expected that the Win32 handle belongs to the current thread. This is not a breaking change as it was previously necessary for the window to be considered "valid". cc rust-windowing/winit#3593 Signed-off-by: John Nunley <dev@notgull.net>
a1b6093
to
582f877
Compare
On Windows, it is generally unsafe to use the HWND outside of the thread that it originates from. In reality, the HWND is an index into a thread-local table, so using it outside of the GUI thread can result in another window being used instead, following by code unsoundness. This is why the WindowHandle type is !Send. However, Window is Send and Sync, which means we have to account for this. Thus far the best solution seems to be to check if we are not in the GUI thread. If we aren't, refuse the return the window handle. For users who want to ensure the safety themselves, the unsafe API was added. Signed-off-by: John Nunley <dev@notgull.net>
582f877
to
beac4e5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given it just adds functionally, it should be good to go.
On Windows, it is generally unsafe to use the HWND outside of the thread
that it originates from. In reality, the HWND is an index into a
thread-local table, so using it outside of the GUI thread can result in
another window being used instead, following by code unsoundness. This
is why the WindowHandle type is !Send. However, Window is Send and Sync,
which means we have to account for this.
Thus far the best solution seems to be to check if we are not in the GUI
thread. If we aren't, refuse the return the window handle.
changelog
module if knowledge of this change could be valuable to users