It is useful to move all the elements out of a hashmap without deallocating
the underlying buffer. It came up in IRC, and this patch implements it as
`drain`.
r? @Gankro
cc: @frankmcsherry
This patch marks `clone` stable, as well as the `Clone` trait, but
leaves `clone_from` unstable. The latter will be decided by the beta.
The patch also marks most manual implementations of `Clone` as stable,
except where the APIs are otherwise deprecated or where there is
uncertainty about providing `Clone`.
This small patch stabilizes the names of all integer modules (including
`int` and `uint`) and the `MIN` and `MAX` constants. The `BITS` and
`BYTES` constants are left unstable for now.
The `is_power_of_two()` method of the `UnsignedInt` trait currently returns `true` for `self == 0`. Zero is not a power of two, assuming an integral exponent `k >= 0`. I've therefore moved this functionality to the new method `is_power_of_two_or_zero()` and reformed `is_power_of_two()` to return false for `self == 0`.
To illustrate the usefulness of the existence of both functions, consider `HashMap`. Its capacity must be zero or a power of two; conversely, it also requires a (non-zero) power of two for key and val alignment.
Also, added a small amount of documentation regarding #18604.
This removes the type SetAlgebraItems and replaces it with the
structs Intersection and Difference.
Rename the existing HashSet iterators according to RFC #344:
* SetItems -> Iter
* SetMoveItems -> IntoIter
* Remaining set combination iterators renamed to Union and SymmetricDifference
[breaking-change]
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
The [final step](https://github.com/rust-lang/rust/pull/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 https://github.com/rust-lang/rust/issues/20012
This is a [breaking-change] for anyone relying on `at_exit`.
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.
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 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#18000
[breaking-change]
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 removes the runtime bookkeeping previously used to ensure
that all Rust tasks were joined before the runtime was shut down.
This functionality will be replaced by an RAII style `Thread` API, that
will also offer a detached mode.
Since this changes the semantics of shutdown, it is a:
[breaking-change]
This commit merges the `rustrt` crate into `std`, undoing part of the
facade. This merger continues the paring down of the runtime system.
Code relying on the public API of `rustrt` will break; some of this API
is now available through `std::rt`, but is likely to change and/or be
removed very soon.
[breaking-change]
- The following operator traits now take their argument by value: `Neg`, `Not`. This breaks all existing implementations of these traits.
- The unary operation `OP a` now "desugars" to `OpTrait::op_method(a)` and consumes its argument.
[breaking-change]
---
r? @nikomatsakis This PR is very similar to the binops-by-value PR
cc @aturon
It is useful to move all the elements out of some collections without
deallocating the underlying buffer. It came up in IRC, and this patch
implements it as `drain`. This has been discussed as part of RFC 509.
r? @Gankro
cc: @frankmcsherry
This commit modifies rustdoc to not require these empty modules to be public in
the standard library. The modules still remain as a location to attach
documentation to, but the modules themselves are now private (don't have to
commit to an API). The documentation for the standard library now shows all of
the primitive types on the main index page.
followed by a semicolon.
This allows code like `vec![1i, 2, 3].len();` to work.
This breaks code that uses macros as statements without putting
semicolons after them, such as:
fn main() {
...
assert!(a == b)
assert!(c == d)
println(...);
}
It also breaks code that uses macros as items without semicolons:
local_data_key!(foo)
fn main() {
println("hello world")
}
Add semicolons to fix this code. Those two examples can be fixed as
follows:
fn main() {
...
assert!(a == b);
assert!(c == d);
println(...);
}
local_data_key!(foo);
fn main() {
println("hello world")
}
RFC #378.
Closes#18635.
[breaking-change]
---
Rebased version of #18958
r? @alexcrichton
cc @pcwalton
followed by a semicolon.
This allows code like `vec![1i, 2, 3].len();` to work.
This breaks code that uses macros as statements without putting
semicolons after them, such as:
fn main() {
...
assert!(a == b)
assert!(c == d)
println(...);
}
It also breaks code that uses macros as items without semicolons:
local_data_key!(foo)
fn main() {
println("hello world")
}
Add semicolons to fix this code. Those two examples can be fixed as
follows:
fn main() {
...
assert!(a == b);
assert!(c == d);
println(...);
}
local_data_key!(foo);
fn main() {
println("hello world")
}
RFC #378.
Closes#18635.
[breaking-change]
Windows dbghelp strips leading underscores from symbols, and I could not find a way to turn this off. So let's accept "ZN...E" form too.
Also, print PC displacement from symbols. This is helpful in gauging whether the PC was indeed within the function displayed in the backtrace, or whether it just happened to be the closest public symbol in the module.
In US english, "that" is used in restrictive clauses in place of
"which", and often affects the meaning of sentences.
In UK english and many dialects, no distinction is
made.
While Rust devs want to avoid unproductive pedanticism, it is worth at
least being uniform in documentation such as:
http://doc.rust-lang.org/std/iter/index.html
and also in cases where correct usage of US english clarifies the
sentence.
This test would read with a timeout and then send a UDP message, expecting the
message to be received. The receiving port, however, was bound in the child
thread so it could be the case that the timeout and send happens before the
child thread runs. To remedy this we just bind the port before the child thread
runs, moving it into the child later on.
cc #19120
Using a type alias for iterator implementations is fragile since this exposes the implementation to users of the iterator, and any changes could break existing code.
This PR changes the iterators of `BTreeMap`, `BTreeSet`, `HashMap`, and `HashSet` to use proper new types, rather than type aliases. However, since it is fair-game to treat a type-alias as the aliased type, this is a:
[breaking-change].
Part of #18469
[breaking-change]
A receiver will only ever get a single auto-reference. Previously arrays and strings would get two, e.g., [T] would be auto-ref'ed to &&[T]. This is usually apparent when a trait is implemented for `&[T]` and has a method takes self by reference. The usual solution is to implement the trait for `[T]` (the DST form).
r? @nikomatsakis (or anyone else, really)
The names expected and actual are not used anymore in the output. It also
removes the confusion that the argument order is the opposite of junit.
Bug #7330 is relevant.
per rfc 459
cc https://github.com/rust-lang/rust/issues/19390
One question is: should we start by warning, and only switch to hard error later? I think we discussed something like this in the meeting.
r? @alexcrichton
Part of #18469
[breaking-change]
A receiver will only ever get a single auto-reference. Previously arrays and strings would get two, e.g., [T] would be auto-ref'ed to &&[T]. This is usually apparent when a trait is implemented for `&[T]` and has a method takes self by reference. The usual solution is to implement the trait for `[T]` (the DST form).
This commit performs a second pass stabilization of the `std::default` module.
The module was already marked `#[stable]`, and the inheritance of `#[stable]`
was removed since this attribute was applied. This commit adds the `#[stable]`
attribute to the trait definition and one method name, along with all
implementations found in the standard distribution.
This commit collapses the various prelude traits for slices into just one trait:
* SlicePrelude/SliceAllocPrelude => SliceExt
* CloneSlicePrelude/CloneSliceAllocPrelude => CloneSliceExt
* OrdSlicePrelude/OrdSliceAllocPrelude => OrdSliceExt
* PartialEqSlicePrelude => PartialEqSliceExt
Using a type alias for iterator implementations is fragile since this
exposes the implementation to users of the iterator, and any changes
could break existing code.
This commit changes the iterators of `HashSet` to use
proper new types, rather than type aliases. However, since it is
fair-game to treat a type-alias as the aliased type, this is a:
[breaking-change].
Using a type alias for iterator implementations is fragile since this
exposes the implementation to users of the iterator, and any changes
could break existing code.
This commit changes the keys and values iterators of `HashMap` to use
proper new types, rather than type aliases. However, since it is
fair-game to treat a type-alias as the aliased type, this is a:
[breaking-change].
- The following operator traits now take their arguments by value: `Add`, `Sub`, `Mul`, `Div`, `Rem`, `BitAnd`, `BitOr`, `BitXor`, `Shl`, `Shr`. This breaks all existing implementations of these traits.
- The binary operation `a OP b` now "desugars" to `OpTrait::op_method(a, b)` and consumes both arguments.
- `String` and `Vec` addition have been changed to reuse the LHS owned value, and to avoid internal cloning. Only the following asymmetric operations are available: `String + &str` and `Vec<T> + &[T]`, which are now a short-hand for the "append" operation.
[breaking-change]
---
This passes `make check` locally. I haven't touch the unary operators in this PR, but converting them to by value should be very similar to this PR. I can work on them after this gets the thumbs up.
@nikomatsakis r? the compiler changes
@aturon r? the library changes. I think the only controversial bit is the semantic change of the `Vec`/`String` `Add` implementation.
cc #19148
On AArch64, libc::c_char is u8. There are some places in the code where i8 is assumed, which causes compilation errors.
(AArch64 is not officially supported yet, but this change does not hurt any other targets and makes the code future-proof.)
In US english, "that" is used in restrictive clauses in place of
"which", and often affects the meaning of sentences.
In UK english and many dialects, no distinction is
made.
While Rust devs want to avoid unproductive pedanticism, it is worth at
least being uniform in documentation such as:
http://doc.rust-lang.org/std/iter/index.html
and also in cases where correct usage of US english clarifies the
sentence.
This commit collapses the various prelude traits for slices into just one trait:
* SlicePrelude/SliceAllocPrelude => SliceExt
* CloneSlicePrelude/CloneSliceAllocPrelude => CloneSliceExt
* OrdSlicePrelude/OrdSliceAllocPrelude => OrdSliceExt
* PartialEqSlicePrelude => PartialEqSliceExt
This test would read with a timeout and then send a UDP message, expecting the
message to be received. The receiving port, however, was bound in the child
thread so it could be the case that the timeout and send happens before the
child thread runs. To remedy this we just bind the port before the child thread
runs, moving it into the child later on.
cc #19120
These probably happened during the merge of the commit that made `Copy` opt-in.
Also, convert the last occurence of `/**` to `///` in `src/libstd/num/strconv.rs`
These probably happened during the merge of the commit that made `Copy` opt-in.
Also, convert the last occurence of `/**` to `///` in `src/libstd/num/strconv.rs`
Brief note: This does *not* affect anything in the prelude
Part of #19253
All this does is remove the reexporting of Result and Option from their
respective modules. More core reexports might be removed, but these ones
are the safest to remove since these enums (and their variants) are included in
the prelude.
Depends on https://github.com/rust-lang/rust/pull/19407 which is merged, but might need a new snapshot
[breaking-change]
Brief note: This does *not* affect anything in the prelude
Part of #19253
All this does is remove the reexporting of Result and Option from their
respective modules. More core reexports might be removed, but these ones
are the safest to remove since these enums (and their variants) are included in
the prelude.
[breaking-change]
This change makes the compiler no longer infer whether types (structures
and enumerations) implement the `Copy` trait (and thus are implicitly
copyable). Rather, you must implement `Copy` yourself via `impl Copy for
MyType {}`.
A new warning has been added, `missing_copy_implementations`, to warn
you if a non-generic public type has been added that could have
implemented `Copy` but didn't.
For convenience, you may *temporarily* opt out of this behavior by using
`#![feature(opt_out_copy)]`. Note though that this feature gate will never be
accepted and will be removed by the time that 1.0 is released, so you should
transition your code away from using it.
This breaks code like:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
Change this code to:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
impl Copy for Point2D {}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
This is the backwards-incompatible part of #13231.
Part of RFC #3.
[breaking-change]
Now that we have an overloaded comparison (`==`) operator, and that `Vec`/`String` deref to `[T]`/`str` on method calls, many `as_slice()`/`as_mut_slice()`/`to_string()` calls have become redundant. This patch removes them. These were the most common patterns:
- `assert_eq(test_output.as_slice(), "ground truth")` -> `assert_eq(test_output, "ground truth")`
- `assert_eq(test_output, "ground truth".to_string())` -> `assert_eq(test_output, "ground truth")`
- `vec.as_mut_slice().sort()` -> `vec.sort()`
- `vec.as_slice().slice(from, to)` -> `vec.slice(from_to)`
---
Note that e.g. `a_string.push_str(b_string.as_slice())` has been left untouched in this PR, since we first need to settle down whether we want to favor the `&*b_string` or the `b_string[]` notation.
This is rebased on top of #19167
cc @alexcrichton @aturon
In regards to:
https://github.com/rust-lang/rust/issues/19253#issuecomment-64836729
This commit:
* Changes the #deriving code so that it generates code that utilizes fewer
reexports (in particur Option::\*, Result::\*, and Ordering::\*), which is necessary to
remove those reexports in the future
* Changes other areas of the codebase so that fewer reexports are utilized
Previously, `BufWriter::write` would just return an `std::io::OtherIoError` if someone attempted to write past the end of the wrapped buffer. This pull request changes the error to support partial writes and return a `std::io::ShortWrite`, or an `io::io::EndOfFile` if it's been fully exhausted.
I've also optimized away a bounds check inside `BufWriter::write`, which should help shave off some nanoseconds in an inner loops.
In regards to:
https://github.com/rust-lang/rust/issues/19253#issuecomment-64836729
This commit:
* Changes the #deriving code so that it generates code that utilizes fewer
reexports (in particur Option::* and Result::*), which is necessary to
remove those reexports in the future
* Changes other areas of the codebase so that fewer reexports are utilized
After the library successfully called `fork(2)`, the child does several
setup works such as setting UID, GID and current directory before it
calls `exec(2)`. When those setup works failed, the child exits but the
parent didn't call `waitpid(2)` and left it as a zombie.
This patch also add several sanity checks. They shouldn't make any
noticeable impact to runtime performance.
The new test case in `libstd/io/process.rs` calls the ps command to check
if the new code can really reap a zombie.
The output of `ps -A -o pid,sid,command` should look like this:
```
PID SID COMMAND
1 1 /sbin/init
2 0 [kthreadd]
3 0 [ksoftirqd/0]
...
12562 9237 ./spawn-failure
12563 9237 [spawn-failure] <defunct>
12564 9237 [spawn-failure] <defunct>
...
12592 9237 [spawn-failure] <defunct>
12593 9237 ps -A -o pid,sid,command
12884 12884 /bin/zsh
12922 12922 /bin/zsh
...
```
where `./spawn-failure` is my test program which intentionally leaves many
zombies. Filtering the output with the "SID" (session ID) column is
a quick way to tell if a process (zombie) was spawned by my own test
program. Then the number of "defunct" lines is the number of zombie
children.
io::stdin returns a new `BufferedReader` each time it's called, which
results in some very confusing behavior with disappearing output. It now
returns a `StdinReader`, which wraps a global singleton
`Arc<Mutex<BufferedReader<StdReader>>`. `Reader` is implemented directly
on `StdinReader`. However, `Buffer` is not, as the `fill_buf` method is
fundamentaly un-thread safe. A `lock` method is defined on `StdinReader`
which returns a smart pointer wrapping the underlying `BufferedReader`
while guaranteeing mutual exclusion.
Code that treats the return value of io::stdin as implementing `Buffer`
will break. Add a call to `lock`:
```rust
io::stdin().read_line();
// =>
io::stdin().lock().read_line();
```
Closes#14434
[breaking-change]
This commit is a reimplementation of `std::sync` to be based on the
system-provided primitives wherever possible. The previous implementation was
fundamentally built on top of channels, and as part of the runtime reform it has
become clear that this is not the level of abstraction that the standard level
should be providing. This rewrite aims to provide as thin of a shim as possible
on top of the system primitives in order to make them safe.
The overall interface of the `std::sync` module has in general not changed, but
there are a few important distinctions, highlighted below:
* The condition variable type, `Condvar`, has been separated out of a `Mutex`.
A condition variable is now an entirely separate type. This separation
benefits users who only use one mutex, and provides a clearer distinction of
who's responsible for managing condition variables (the application).
* All of `Condvar`, `Mutex`, and `RWLock` are now directly built on top of
system primitives rather than using a custom implementation. The `Once`,
`Barrier`, and `Semaphore` types are still built upon these abstractions of
the system primitives.
* The `Condvar`, `Mutex`, and `RWLock` types all have a new static type and
constant initializer corresponding to them. These are provided primarily for C
FFI interoperation, but are often useful to otherwise simply have a global
lock. The types, however, will leak memory unless `destroy()` is called on
them, which is clearly documented.
* The fundamental architecture of this design is to provide two separate layers.
The first layer is that exposed by `sys_common` which is a cross-platform
bare-metal abstraction of the system synchronization primitives. No attempt is
made at making this layer safe, and it is quite unsafe to use! It is currently
not exported as part of the API of the standard library, but the stabilization
of the `sys` module will ensure that these will be exposed in time. The
purpose of this layer is to provide the core cross-platform abstractions if
necessary to implementors.
The second layer is the layer provided by `std::sync` which is intended to be
the thinnest possible layer on top of `sys_common` which is entirely safe to
use. There are a few concerns which need to be addressed when making these
system primitives safe:
* Once used, the OS primitives can never be **moved**. This means that they
essentially need to have a stable address. The static primitives use
`&'static self` to enforce this, and the non-static primitives all use a
`Box` to provide this guarantee.
* Poisoning is leveraged to ensure that invalid data is not accessible from
other tasks after one has panicked.
In addition to these overall blanket safety limitations, each primitive has a
few restrictions of its own:
* Mutexes and rwlocks can only be unlocked from the same thread that they
were locked by. This is achieved through RAII lock guards which cannot be
sent across threads.
* Mutexes and rwlocks can only be unlocked if they were previously locked.
This is achieved by not exposing an unlocking method.
* A condition variable can only be waited on with a locked mutex. This is
achieved by requiring a `MutexGuard` in the `wait()` method.
* A condition variable cannot be used concurrently with more than one mutex.
This is guaranteed by dynamically binding a condition variable to
precisely one mutex for its entire lifecycle. This restriction may be able
to be relaxed in the future (a mutex is unbound when no threads are
waiting on the condvar), but for now it is sufficient to guarantee safety.
* Condvars support timeouts for their blocking operations. The
implementation for these operations is provided by the system.
Due to the modification of the `Condvar` API, removal of the `std::sync::mutex`
API, and reimplementation, this is a breaking change. Most code should be fairly
easy to port using the examples in the documentation of these primitives.
[breaking-change]
Closes#17094Closes#18003
This commit is a reimplementation of `std::sync` to be based on the
system-provided primitives wherever possible. The previous implementation was
fundamentally built on top of channels, and as part of the runtime reform it has
become clear that this is not the level of abstraction that the standard level
should be providing. This rewrite aims to provide as thin of a shim as possible
on top of the system primitives in order to make them safe.
The overall interface of the `std::sync` module has in general not changed, but
there are a few important distinctions, highlighted below:
* The condition variable type, `Condvar`, has been separated out of a `Mutex`.
A condition variable is now an entirely separate type. This separation
benefits users who only use one mutex, and provides a clearer distinction of
who's responsible for managing condition variables (the application).
* All of `Condvar`, `Mutex`, and `RWLock` are now directly built on top of
system primitives rather than using a custom implementation. The `Once`,
`Barrier`, and `Semaphore` types are still built upon these abstractions of
the system primitives.
* The `Condvar`, `Mutex`, and `RWLock` types all have a new static type and
constant initializer corresponding to them. These are provided primarily for C
FFI interoperation, but are often useful to otherwise simply have a global
lock. The types, however, will leak memory unless `destroy()` is called on
them, which is clearly documented.
* The `Condvar` implementation for an `RWLock` write lock has been removed. This
may be added back in the future with a userspace implementation, but this
commit is focused on exposing the system primitives first.
* The fundamental architecture of this design is to provide two separate layers.
The first layer is that exposed by `sys_common` which is a cross-platform
bare-metal abstraction of the system synchronization primitives. No attempt is
made at making this layer safe, and it is quite unsafe to use! It is currently
not exported as part of the API of the standard library, but the stabilization
of the `sys` module will ensure that these will be exposed in time. The
purpose of this layer is to provide the core cross-platform abstractions if
necessary to implementors.
The second layer is the layer provided by `std::sync` which is intended to be
the thinnest possible layer on top of `sys_common` which is entirely safe to
use. There are a few concerns which need to be addressed when making these
system primitives safe:
* Once used, the OS primitives can never be **moved**. This means that they
essentially need to have a stable address. The static primitives use
`&'static self` to enforce this, and the non-static primitives all use a
`Box` to provide this guarantee.
* Poisoning is leveraged to ensure that invalid data is not accessible from
other tasks after one has panicked.
In addition to these overall blanket safety limitations, each primitive has a
few restrictions of its own:
* Mutexes and rwlocks can only be unlocked from the same thread that they
were locked by. This is achieved through RAII lock guards which cannot be
sent across threads.
* Mutexes and rwlocks can only be unlocked if they were previously locked.
This is achieved by not exposing an unlocking method.
* A condition variable can only be waited on with a locked mutex. This is
achieved by requiring a `MutexGuard` in the `wait()` method.
* A condition variable cannot be used concurrently with more than one mutex.
This is guaranteed by dynamically binding a condition variable to
precisely one mutex for its entire lifecycle. This restriction may be able
to be relaxed in the future (a mutex is unbound when no threads are
waiting on the condvar), but for now it is sufficient to guarantee safety.
* Condvars now support timeouts for their blocking operations. The
implementation for these operations is provided by the system.
Due to the modification of the `Condvar` API, removal of the `std::sync::mutex`
API, and reimplementation, this is a breaking change. Most code should be fairly
easy to port using the examples in the documentation of these primitives.
[breaking-change]
Closes#17094Closes#18003
This may have inadvertently switched during the runtime overhaul, so this
switches TcpListener back to using sockets instead of file descriptors. This
also renames a bunch of variables called `fd` to `socket` to clearly show that
it's not a file descriptor.
Closes#19333
After the library successfully called fork(2), the child does several
setup works such as setting UID, GID and current directory before it
calls exec(2). When those setup works failed, the child exits but the
parent didn't call waitpid(2) and left it as a zombie.
This patch also add several sanity checks. They shouldn't make any
noticeable impact to runtime performance.
The new test case run-pass/wait-forked-but-failed-child.rs calls the ps
command to check if the new code can really reap a zombie. When
I intentionally create many zombies with my test program
./spawn-failure, The output of "ps -A -o pid,sid,command" should look
like this:
PID SID COMMAND
1 1 /sbin/init
2 0 [kthreadd]
3 0 [ksoftirqd/0]
...
12562 9237 ./spawn-failure
12563 9237 [spawn-failure] <defunct>
12564 9237 [spawn-failure] <defunct>
...
12592 9237 [spawn-failure] <defunct>
12593 9237 ps -A -o pid,sid,command
12884 12884 /bin/zsh
12922 12922 /bin/zsh
...
Filtering the output with the "SID" (session ID) column is a quick way
to tell if a process (zombie) was spawned by my own test program. Then
the number of "defunct" lines is the number of zombie children.
Signed-off-by: NODA, Kai <nodakai@gmail.com>
On *BSD systems, we can `open(2)` a directory and directly `read(2)` from it due to an old tradition. We should avoid doing so by explicitly calling `fstat(2)` to check the type of the opened file.
Opening a directory as a module file can't always be avoided. Even when there's no "path" attribute trick involved, there can always be a *directory* named `my_module.rs`.
Incidentally, remove unnecessary mutability of `&self` from `io::fs::File::stat()`.
This continues the work @thestinger started in #18885 (which hasn't landed yet, so wait for that to land before landing this one). Instead of adding more methods to `BufReader`, this just allows a `&[u8]` to be used directly as a `Reader`. It also adds an impl of `Writer` for `&mut [u8]`.
Comparison traits have gained an `Rhs` input parameter that defaults to `Self`. And now the comparison operators can be overloaded to work between different types. In particular, this PR allows the following operations (and their commutative versions):
- `&str` == `String` == `CowString`
- `&[A]` == `&mut [B]` == `Vec<C>` == `CowVec<D>` == `[E, ..N]` (for `N` up to 32)
- `&mut A` == `&B` (for `Sized` `A` and `B`)
Where `A`, `B`, `C`, `D`, `E` may be different types that implement `PartialEq`. For example, these comparisons are now valid: `string == "foo"`, and `vec_of_strings == ["Hello", "world"]`.
[breaking-change]s
Since the `==` may now work on different types, operations that relied on the old "same type restriction" to drive type inference, will need to be type annotated. These are the most common fallout cases:
- `some_vec == some_iter.collect()`: `collect` needs to be type annotated: `collect::<Vec<_>>()`
- `slice == &[a, b, c]`: RHS doesn't get coerced to an slice, use an array instead `[a, b, c]`
- `lhs == []`: Change expression to `lhs.is_empty()`
- `lhs == some_generic_function()`: Type annotate the RHS as necessary
cc #19148
r? @aturon
io::stdin returns a new `BufferedReader` each time it's called, which
results in some very confusing behavior with disappearing output. It now
returns a `StdinReader`, which wraps a global singleton
`Arc<Mutex<BufferedReader<StdReader>>`. `Reader` is implemented directly
on `StdinReader`. However, `Buffer` is not, as the `fill_buf` method is
fundamentaly un-thread safe. A `lock` method is defined on `StdinReader`
which returns a smart pointer wrapping the underlying `BufferedReader`
while guaranteeing mutual exclusion.
Code that treats the return value of io::stdin as implementing `Buffer`
will break. Add a call to `lock`:
```rust
io::stdin().lines()
// =>
io::stdin().lock().lines()
```
Closes#14434
[breaking-change]
On *BSD systems, we can open(2) a directory and directly read(2) from
it due to an old tradition. We should avoid doing so by explicitly
calling fstat(2) to check the type of the opened file.
Opening a directory as a module file can't always be avoided.
Even when there's no "path" attribute trick involved, there can always
be a *directory* named "my_module.rs".
Fix#12460
Signed-off-by: NODA, Kai <nodakai@gmail.com>