Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upunsafe: ScopedKey allows for Sync-ification of non-Sync data #25894
Comments
This comment has been minimized.
This comment has been minimized.
Gankro
added
I-nominated
P-high
T-libs
labels
May 30, 2015
Manishearth
added
the
A-threads
label
May 30, 2015
Manishearth
added a commit
to Manishearth/rust
that referenced
this issue
May 30, 2015
Manishearth
referenced this issue
May 30, 2015
Closed
thread: Add Sync bound to ScopedKey (fixes #25894) #25897
Manishearth
added a commit
to Manishearth/rust
that referenced
this issue
May 30, 2015
This comment has been minimized.
This comment has been minimized.
|
This seems concerning: this is designed to be thread-local, so that e.g. storing a |
This comment has been minimized.
This comment has been minimized.
|
Qualifying the impl with |
This comment has been minimized.
This comment has been minimized.
|
I believe the only way
The main issue is actually within the libstd TLS implementation:
Should |
This comment has been minimized.
This comment has been minimized.
|
"I believe the only way #[thread_local] statics can be safe is by requiring the absence of This is wrong, I think. For example, one might use thread local data for intrusive linked lists of hazard pointers. They would be thread local but might still be |
This comment has been minimized.
This comment has been minimized.
|
Based on what @eddyb wrote, it seems like the TLS interface requires a One idea I had of how to enable this in todays Rust is to make
According to @eddyb, this could also help with |
This comment has been minimized.
This comment has been minimized.
|
@Kimundi I was expecting the @pythonesque You would still be about to use the TLS API provided by libstd with thread-safe data, it's just the low-level Ideas of thread-local lifetimes predate the removal of Actually, there's an... easy solution for this. Somehow we were blinded by language semantics, but their details are fluid. That would ensure that the the thread is just as alive for such borrows as it is for stack ones. |
This comment has been minimized.
This comment has been minimized.
|
Wouldn't that limit the usability of thread locals in some cases, though? e.g., wouldn't that make it difficult to have a thread local point to another thread local? Maybe I just have to think about it. (BTW, I'm aware we're just talking about the low-level API :)). |
This comment has been minimized.
This comment has been minimized.
|
@pythonesque in a We could disallow Which makes me think, as a compromise between a They would behave as if they were borrowed before everything else in the function where they're used, but still not |
This comment has been minimized.
This comment has been minimized.
|
There's a few intertwined issues here at play, so I just want to quickly summarize the way I see things:
I'm not sure I follow why we might require the types in a |
This comment has been minimized.
This comment has been minimized.
|
triage: P-medium This is an unstable API so it's not super-high priority to fix, but we should defnitely fix! |
rust-highfive
added
P-medium
and removed
P-high
I-nominated
labels
Jun 1, 2015
This comment has been minimized.
This comment has been minimized.
|
@alexcrichton requiring that a I've changed my mind and prefer an rvalue borrow semantic for If Maybe a combined strategy, where borrows of |
This comment has been minimized.
This comment has been minimized.
Right, but returning a borrow with a |
This comment has been minimized.
This comment has been minimized.
|
@alexcrichton how can it be abused without sending it to a different thread? |
This comment has been minimized.
This comment has been minimized.
The actual values themselves do not have a |
Manishearth commentedMay 30, 2015
There is an
unsafe impl<T> Sync for KeyInner<T> { }in the scoped TLS module, which allows for sharing of data that wasn't meant to be shared.An unqualified
unsafe impl<T> Sync for Foo { }should only be used whenFooprovides some sort of threadsafe locking mechanism.KeyInnerandScopedKeydo not.This lets us, for example, clone an
RcorRefCellbetween threads, in safe code:playpen
Here, we have
Rcclones from different threads being interleaved, which can cause unsafety if there's a race on the refcount. We could also cause unsafety with aRefCell, or any other non-Sync type.ScopedKeybasically lets us share&Tacross threads even ifT: !Sync. I put the sleeps in there because somehow without them the routines are run serially.Note that this is not a problem with the
scoped()API. I'm usingscoped()here because to exploit&T: Send, T:!Syncone needs to be able to share across threads, andArchas an additionalSendbound whichScopedKeydoesn't satisfy. Any usablescopedAPI will probably have to make the assumption that&T: Send iff T:Sync. Nor is this a problem withRc, since it can be done withRefCell, too.Solution: Make it
unsafe impl<T: Sync> Sync for KeyInner<T> { }... I think. I'm not familiar with this API, and I'm not sure why it's even
Syncin the first place.