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

fix(settings): mark drop guard as !Send #695

Merged

Conversation

jalil-salame
Copy link
Contributor

Fixes #694

Because the SettingsDropGuard modifies a ThreadLocalKey (it clones it in the Settings::bind_to_scope method, then restores it in its drop impl), it should not be moved to a different thread, as then it would modify that thread's CURRENT_SETTINGS instead of the original thread's.

This is not an issue with normal code as the guard is usually unnameable (let _guard = settings.bind_to_scope();). but it is a problem with async code, as when held across await points is can be moved by the runtime to a separate thread.

We fix it by adding a PhantomData field to SettingsDropGuard that does not implement Send. We verify it works by adding a compile_fail doctest to the struct that tries to send the drop guard to a different thread.

Fixes mitsuhiko#694

Because the `SettingsDropGuard` modifies a `ThreadLocalKey` (it clones
it in the `Settings::bind_to_scope` method, then restores it in its drop
impl), it should not be moved to a different thread, as then it would
modify that thread's `CURRENT_SETTINGS` instead of the original
thread's.

This is not an issue with normal code as the guard is usually unnameable
(`let _guard = settings.bind_to_scope();`). but it is a problem with
`async` code, as when held across `await` points is can be moved by the
runtime to a separate thread.

We fix it by adding a `PhantomData` field to `SettingsDropGuard` that
does not implement `Send`. We verify it works by adding a `compile_fail`
doctest to the struct that tries to send the drop guard to a different
thread.
@jalil-salame
Copy link
Contributor Author

This is technically a breaking change, but it is a logic error, so I would argue it is not breaking as users relying on this functionality had broken tests already

@max-sixty
Copy link
Collaborator

I'm not an expert here, but in principle it makes a lot of sense. I'll merge unless @mitsuhiko has any feedback in the next day or so.

@jalil-salame if you'd be up for adding a one-sentence description to the Changelog (+ an attribution if you'd like), that would be great!

@jalil-salame
Copy link
Contributor Author

@jalil-salame if you'd be up for adding a one-sentence description to the Changelog (+ an attribution if you'd like), that would be great!

Done!

@max-sixty max-sixty merged commit 0caaaca into mitsuhiko:master Dec 18, 2024
@jalil-salame jalil-salame deleted the settings-drop-guard-not-send-impl branch December 18, 2024 19:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Settings::bind_to_scope()'s drop guard is Send
2 participants