-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Replace std::task
with std::thread
, remove librustrt, make final "runtime" features lazily initialize
#19654
Conversation
Note: this PR does not attempt to exhaustively replace the |
Note also: the implementation of |
cc @thestinger |
@@ -92,7 +92,7 @@ impl<'a, T, Sized? B> BorrowFrom<Cow<'a, T, B>> for B where B: ToOwned<T> { | |||
|
|||
/// Trait for moving into a `Cow` | |||
pub trait IntoCow<'a, T, Sized? B> { | |||
/// Moves `self` into `Cow` | |||
/// Moves `serlf` into `Cow` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
serlf
Once piece of feedback I'd like: is |
no_send: NoSend, | ||
} | ||
|
||
pub fn tokens() -> (WaitToken, SignalToken) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity, doesn't this abstraction break if the thread is blocked on anything other than WaitToken
while some SignalToken
s are signaled? I'm thinking that you call tokens
, signal the token, manually call Thread::park()
, and then call wait
, you'd sleep forever, right? That seems pretty silly though, and I imagine we could document this example when it's a public-facing API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's correct that you won't get unparked by that signal, but you could be unparked by a different signal. But in any case, you're probably doing something wrong.
(Note that the intent of structures like this and park/unpark is for building blocking concurrency abstractions like channels; they aren't a good fit for application-level concurrent programming. See http://gee.cs.oswego.edu/dl/papers/aqs.pdf)
There's always a fun time having two sets of standard libraries when testing!
We need to be sure to init thread_info before we init args for example because args is grabbing locks which may entail looking at the local thread eventually.
This commit is part of a series that introduces a `std::thread` API to replace `std::task`. In the new API, `spawn` returns a `JoinGuard`, which by default will join the spawned thread when dropped. It can also be used to join explicitly at any time, returning the thread's result. Alternatively, the spawned thread can be explicitly detached (so no join takes place). As part of this change, Rust processes now terminate when the main thread exits, even if other detached threads are still running, moving Rust closer to standard threading models. This new behavior may break code that was relying on the previously implicit join-all. In addition to the above, the new thread API also offers some built-in support for building blocking abstractions in user space; see the module doc for details. Closes rust-lang#18000 [breaking-change]
The current implementations use `std::sync` primitives, but these primitives currently end up relying on `thread_info` and a local `Thread` being available (mainly for checking the panicking flag). To get around this, this commit lowers the abstractions used by the windows thread_local implementation as well as the at_exit_imp module. Both of these modules now use a `sys::Mutex` and a `static mut` and manage the allocation/locking manually.
This flag is somewhat tied to the `unwind` module rather than the `thread_info` module, so this commit moves it into that module as well as allowing the same OS thread to call `unwind::try` multiple times. Previously once a thread panicked its panic flag was never reset, even after exiting the panic handler.
... and address other rebasing fallout.
The [final step](rust-lang#19654) of runtime removal changes the threading/process model so that the process shuts down when the main thread exits. But several shared resources, like the helper thread for timeouts, are shut down when the main thread exits (but before the process ends), and they are not prepared to be used after shut down, but other threads may try to access them during the shutdown sequence of the main thread. As an interim solution, the `at_exit` cleanup routine is simply skipped. Ultimately, these resources should be made to safely handle asynchronous shutdown, usually by panicking if called from a detached thread when the main thread is ending. See issue for details rust-lang#20012 This is a [breaking-change] for anyone relying on `at_exit`.
This PR substantially narrows the notion of a "runtime" in Rust, and allows calling into Rust code directly without any setup or teardown. After this PR, the basic "runtime support" in Rust will consist of: * Unwinding and backtrace support * Stack guards Other support, such as helper threads for timers or the notion of a "current thread" are initialized automatically upon first use. When using Rust in an embedded context, it should now be possible to call a Rust function directly as a C function with absolutely no setup, though in that case panics will cause the process to abort. In this regard, the C/Rust interface will look much like the C/C++ interface. In more detail, this PR: * Merges `librustrt` back into `std::rt`, undoing the facade. While doing so, it removes a substantial amount of redundant functionality (such as mutexes defined in the `rt` module). Code using `librustrt` can now call into `std::rt` to e.g. start executing Rust code with unwinding support. * Allows all runtime data to be initialized lazily, including the "current thread", the "at_exit" infrastructure, and the "args" storage. * Deprecates and largely removes `std::task` along with the widespread requirement that there be a "current task" for many APIs in `std`. The entire task infrastructure is replaced with `std::thread`, which provides a more standard API for manipulating and creating native OS threads. In particular, it's possible to join on a created thread, and to get a handle to the currently-running thread. In addition, threads are equipped with some basic blocking support in the form of `park`/`unpark` operations (following a tradition in some OSes as well as the JVM). See the `std::thread` documentation for more details. * Channels are refactored to use a new internal blocking infrastructure that itself sits on top of `park`/`unpark`. One important change here is that a Rust program ends when its main thread does, following most threading models. On the other hand, threads will often be created with an RAII-style join handle that will re-institute blocking semantics naturally (and with finer control). This is very much a: [breaking-change] Closes #18000 r? @alexcrichton
|
It also sort of suggested that they were builtin constructs, which I think their removal from the prelude is supposed to prevent. |
@bluss You might want to leave a comment at rust-lang/rfcs#503, which talks about the future of the prelude. |
This PR substantially narrows the notion of a "runtime" in Rust, and allows calling into Rust code directly without any setup or teardown.
After this PR, the basic "runtime support" in Rust will consist of:
Other support, such as helper threads for timers or the notion of a "current thread" are initialized automatically upon first use.
When using Rust in an embedded context, it should now be possible to call a Rust function directly as a C function with absolutely no setup, though in that case panics will cause the process to abort. In this regard, the C/Rust interface will look much like the C/C++ interface.
In more detail, this PR:
librustrt
back intostd::rt
, undoing the facade. While doing so, it removes a substantial amount of redundant functionality (such as mutexes defined in thert
module). Code usinglibrustrt
can now call intostd::rt
to e.g. start executing Rust code with unwinding support.std::task
along with the widespread requirement that there be a "current task" for many APIs instd
. The entire task infrastructure is replaced withstd::thread
, which provides a more standard API for manipulating and creating native OS threads. In particular, it's possible to join on a created thread, and to get a handle to the currently-running thread. In addition, threads are equipped with some basic blocking support in the form ofpark
/unpark
operations (following a tradition in some OSes as well as the JVM). See thestd::thread
documentation for more details.park
/unpark
.One important change here is that a Rust program ends when its main thread does, following most threading models. On the other hand, threads will often be created with an RAII-style join handle that will re-institute blocking semantics naturally (and with finer control).
This is very much a:
[breaking-change]
Closes #18000
r? @alexcrichton