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

Ensure joy_connection_changed is emitted on the main thread #80432

Merged
merged 1 commit into from
Aug 9, 2023

Conversation

rsubtil
Copy link
Contributor

@rsubtil rsubtil commented Aug 8, 2023

Closes #78531 (once cherry-picked for 3.x)

On Linux, the code for querying joypad status runs in a thread (JoypadLinux::joypad_events_thread_run). Therefore, the joy_connection_changed signal is not emitted on the main thread, which depending on user code, can lead do a deadlock due to thread-unsafe API.

@rsubtil rsubtil requested a review from a team as a code owner August 8, 2023 21:00
@@ -475,7 +475,7 @@ void Input::joy_connection_changed(int p_idx, bool p_connected, String p_name, S
}
joy_names[p_idx] = js;

emit_signal(SNAME("joy_connection_changed"), p_idx, p_connected);
call_deferred("emit_signal", SNAME("joy_connection_changed"), p_idx, p_connected);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add a comment to clarify, like "Defer to emit on the main thread." (IIUC).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW I'm not good with multithreading, but would deferring the call to joy_connection_changed in the Linux input code solve the issue similarly?

If only some platforms do this in a thread, maybe they should be responsible for deferring to the main thread where needed?

Though this one claims to be thread-safe so I guess this helps provide this guarantee?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, from what I've checked it seems only Linux runs on a thread, and I did try making this change there initially. But for some reason, it didn't work: on Godot 4, the signal stopped being emitted altogether; on Godot 3, the signal stopped being emitted when a joypad is disconnected, and every time I reconnected the joypad it registered a new device index.

@akien-mga akien-mga added bug platform:linuxbsd topic:input cherrypick:3.x Considered for cherry-picking into a future 3.x release cherrypick:3.5 Considered for cherry-picking into a future 3.5.x release cherrypick:4.0 cherrypick:4.1 Considered for cherry-picking into a future 4.1.x release labels Aug 9, 2023
@akien-mga akien-mga added this to the 4.2 milestone Aug 9, 2023
@akien-mga akien-mga merged commit 5cfa9a0 into godotengine:master Aug 9, 2023
15 checks passed
@akien-mga
Copy link
Member

Thanks!

@rsubtil rsubtil deleted the fix_linux_joypad_on_thread branch August 9, 2023 15:56
@akien-mga
Copy link
Member

Cherry-picked for 3.6.

@akien-mga akien-mga removed the cherrypick:3.x Considered for cherry-picking into a future 3.x release label Aug 28, 2023
@akien-mga
Copy link
Member

Cherry-picked for 3.5.3.

@akien-mga akien-mga removed the cherrypick:3.5 Considered for cherry-picking into a future 3.5.x release label Aug 28, 2023
@YuriSizov YuriSizov removed the cherrypick:4.1 Considered for cherry-picking into a future 4.1.x release label Sep 21, 2023
@YuriSizov
Copy link
Contributor

Cherry-picked for 4.1.2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Engine freezes when calling Sprite.new() from joy_connection_changed callback
3 participants