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

Tracking issue for thread_local_state stabilization #27716

Closed
aturon opened this issue Aug 12, 2015 · 18 comments
Closed

Tracking issue for thread_local_state stabilization #27716

aturon opened this issue Aug 12, 2015 · 18 comments
Labels
B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@aturon
Copy link
Member

aturon commented Aug 12, 2015

This feature allows you to query a thread-local variable for its state: http://static.rust-lang.org/doc/master/std/thread/enum.LocalKeyState.html, which will then tell you what may happen if you try to read from the variable.

The functionality is somewhat niche, but occasionally essential. The APIs appear to be in pretty decent shape as-is.

cc @alexcrichton

@aturon aturon added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. B-unstable Blocker: Implemented in the nightly compiler and unstable. labels Aug 12, 2015
@alexcrichton alexcrichton added the E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. label Aug 13, 2015
@Manishearth Manishearth removed the E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. label Oct 2, 2015
@aturon
Copy link
Member Author

aturon commented Nov 4, 2015

Nominating for stabilization in 1.6.

@alexcrichton
Copy link
Member

The libs team decided to not move this into FCP, some worries around this being:

  • Checking the state and then accessing hits TLS twice, which may be too slow for some use cases.
  • This is very similar to RefCell::borrow_state which has also not yet been stabilized. It's likely that the enum here wants to move to boolean accessors so we can add more states in the future.

@alexcrichton
Copy link
Member

Although I nominated this for 1.8, libs decided to remove the nomination as I forgot that the reason this is not in FCP yet is because you hit TLS twice when querying the state.

@apasel422
Copy link
Contributor

I think this would be better expressed like RefCell::try_borrow.

@PlasmaPower
Copy link
Contributor

See also: rust-lang/rfcs#2030

@PlasmaPower
Copy link
Contributor

PR for try_with (similar to RefCell::try_borrow) wrapped into this feature: #43158

bors added a commit that referenced this issue Jul 13, 2017
Thread local try with

rust-lang/rfcs#2030 was turned into this PR (the RFC was closed, but it looks like just a PR should be good).

See also: state stabilization issue: #27716

`try_with` is used in two places in std: stdio and thread_info. In stdio, it would be better if the result was passed to the closure, but in thread_info, it's better as is where the result is returned from the function call. I'm not sure which is better, but I prefer the current way as it better represents the scope.
@Mark-Simulacrum Mark-Simulacrum added the C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC label Jul 22, 2017
@ghost
Copy link

ghost commented Oct 13, 2017

The documenation for LocalKey::state says:

A key is initially in the Uninitialized state whenever a thread starts. It will remain in this state up until the first call to with within a thread has run the initialization expression successfully. Once the initialization expression succeeds, the key transitions to the Valid state which will guarantee that future calls to with will succeed within the thread.

But then it also mentions:

Keys may remain in the Destroyed state after destruction has completed. Keys without destructors (e.g. with types that are Copy), may never enter the Destroyed state.

Do we really want to make the first guarantee? Is it not reasonable for Copy types to skip the Uninitialized state altogether and start right off in the Valid state?

@joshlf
Copy link
Contributor

joshlf commented Oct 14, 2017

+1 to that.

@alexcrichton
Copy link
Member

@stjepang sounds reasonable to me!

@ghost
Copy link

ghost commented Oct 17, 2017

Checking the state and then accessing hits TLS twice, which may be too slow for some use cases.

This issue should be resolved now that we have LocalKey::try_with.

This is very similar to RefCell::borrow_state which has also not yet been stabilized. It's likely that the enum here wants to move to boolean accessors so we can add more states in the future.

borrow_state was rejected in favor of try_borrow.
Apart from Unitialized, Valid, and Destroyed state, what may the additional states even be? Is this still a concern? If not, are we ready to kick off FCP?

@joshlf
Copy link
Contributor

joshlf commented Oct 17, 2017

Apart from Unitialized, Valid, and Destroyed state, what may the additional states even be? Is this still a concern?

In #43491, I proposed adding a fourth Initializing state between Uninitialized and Valid. The idea was to allow detection of initialization loops. My particular goal was to support allocators (e.g., elfmalloc relies on crossbeam, which in turn allocates, etc), and I opened PR #43550, but it was eventually closed when we discovered that there was no good way to transition keys into Initializing before performing any allocation on platforms that don't support the #[thread_local] attribute. Instead, I updated the documentation (#44396) to clarify that recursively-dependent initializers are not supported.

kennytm added a commit to kennytm/rust that referenced this issue Oct 18, 2017
…initialized, r=alexcrichton

Docs: a LocalKey might start in the Valid state

Add a comment to the docs for `LocalKey::state` explaining that some keys might skip the `Uninitialized` state and start in the `Valid` state.

cc rust-lang#27716

r? @alexcrichton
@ghost
Copy link

ghost commented Nov 19, 2017

Until we decide what to do with LocalKeyState, could we stabilize the try_with method only?
I don't see any blockers for that.

@Mark-Simulacrum
Copy link
Member

Nominating. I propose that we stabilize the LocalKey::try_with method and deprecate the LocalKey::state method and associated enum. I don't see a good usecase for the enum given this method.

cc @rust-lang/libs

@alexcrichton
Copy link
Member

I agree with @Mark-Simulacrum's assessment and would be ok stabilizing try_with!

@rfcbot fcp merge

@rfcbot
Copy link

rfcbot commented Jan 23, 2018

Team member @alexcrichton has proposed to merge this. The next step is review by the rest of the tagged teams:

No concerns currently listed.

Once these reviewers reach consensus, this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added the proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. label Jan 23, 2018
@rfcbot rfcbot added final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. and removed proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. labels Feb 14, 2018
@rfcbot
Copy link

rfcbot commented Feb 14, 2018

🔔 This is now entering its final comment period, as per the review above. 🔔

@rfcbot
Copy link

rfcbot commented Feb 24, 2018

The final comment period is now complete.

Manishearth added a commit to Manishearth/rust that referenced this issue Mar 1, 2018
…h, r=alexcrichton

Stabilize LocalKey::try_with

The `LocalKey::try_with` method is now stabilized.

`LocalKey::state` and `LocalKeyState` marked as deprecated. Although, is there any reason to keep them - should we perhaps remove them completely?

Closes rust-lang#27716

r? @alexcrichton
@ghost
Copy link

ghost commented Sep 11, 2018

I regret stabilizing LocalKey::try_with with the current signature. :(

So the signature of LocalKey::try_with is:

pub fn try_with<F, R>(&'static self, f: F) -> Result<R, AccessError>
where
    F: FnOnce(&T) -> R;

We should've gone with the following instead:

pub fn try_with<F, R>(&'static self, f: F) -> R
where
    F: FnOnce(Result<&T, AccessError>) -> R;

Why? I have a situation with this helper function:

pub fn with_context<F, R>(f: F) -> R
where
    F: FnOnce(&Arc<Context>) -> R,
{
    CONTEXT.try_with(|cx| f(cx)).unwrap_or_else(|_| f(&Context::new()))
}

Unfortunately, the helper function doesn't compile:

error[E0382]: capture of moved value: `f`
   --> src/internal/context.rs:162:53
    |
162 |     CONTEXT.try_with(|cx| f(cx)).unwrap_or_else(|_| f(&Context::new()))
    |                      ----                           ^ value captured here after move
    |                      |
    |                      value moved (into closure) here
    |
    = note: move occurs because `f` has type `F`, which does not implement the `Copy` trait

So F has to be FnMut or additionally Copy, which is annoying.

Had we gone with the other signature for LocalKey::with, this would be easy to do:

pub fn with_context<F, R>(f: F) -> R
where
    F: FnOnce(&Arc<Context>) -> R,
{
    CONTEXT.try_with(|cx| {
        match cx {
            Ok(cx) => f(cx),
            Err(..) => f(&Context::new()),
        }
    })
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

8 participants