SergioBenitez / state

A Rust library for safe and effortless global and thread-local state management.
Other
213 stars 14 forks source link

Use thread_local's try_with() to handle TLS errors without panicking. #26

Closed laomaiweng closed 1 year ago

laomaiweng commented 2 years ago

Hi,

I've been bitten by a panic when using LocalStorage in weird circumstances, even with try_get(). Namely, my code (in an LD_PRELOAD library) was being called after TLS destructors had been called during libc finalization, and this caused a panic within THREAD_ID.with() in thread_local::get().

This PR attempts to fix this by using THREAD_ID.try_with() and returning an Option (which is what THREAD_ID.with() does internally, it just unwraps the option afterwards). When using LocalStorage::get(), the option is optimistically unwrapped, so this could still result in panics (in edge cases), but that's expected with get(). However now when using LocalStorage::try_get(), None will be returned if either the value has not been set (as previously), or the TLS-stored thread ID has been destroyed (new from this PR).

I don't really know how to test this edge case, so I didn't add a test for it, sorry. :-/ Please do not hesitate to suggest edits if need be.

Cheers and thanks for this great crate!

SergioBenitez commented 1 year ago

Thank you for this. Apologies for the tardiness. I've pushed this in https://github.com/SergioBenitez/state/commit/f2c3575507d6a0a4f10f36a1e7652be4837d3040.