libc is only used when the heap allocations are not defined externally, or defined in another crate. I assume these extern* configurations were added for the sake of those of us experimenting with freestanding Rust. Avoiding libc where possible is often very important for us.
This commit prepares the liblibc library to be moved to crates.io. Unlike the
log, serialize, term, etc crates, the source for this crate will *not* be
duplicated out-of-tree. Instead a new rust-lang/libc repository will be created
with a submodule to this repository and it will use the source directly.
In order to compile within the stable ecosystem of Rust, this crate cannot link
to libcore, and it also needs some tweaks for the other attributes that it has.
As a result this commit tweaks the source of the crate to link to libcore when
built in tree but link to libstd when built via cargo.
Note that the rust-lang/libc crate isn't quite prepared just yet, there's a
Cargo bug or two that I'd like to iron out before publishing it. This is simply
preparing the in-tree source.
This commit prepares the liblibc library to be moved to crates.io. Unlike the
log, serialize, term, etc crates, the source for this crate will *not* be
duplicated out-of-tree. Instead a new rust-lang/libc repository will be created
with a submodule to this repository and it will use the source directly.
In order to compile within the stable ecosystem of Rust, this crate cannot link
to libcore, and it also needs some tweaks for the other attributes that it has.
As a result this commit tweaks the source of the crate to link to libcore when
built in tree but link to libstd when built via cargo.
Note that the rust-lang/libc crate isn't quite prepared just yet, there's a
Cargo bug or two that I'd like to iron out before publishing it. This is simply
preparing the in-tree source.
Believe or not, `CreateProcess()` is racy if several threads create
child processes: [0], [1], [2].
This caused some tests show crash dialogs during
`make check-stage#-rpass`.
More explanation:
On Windows, `SetErrorMode()` controls display of error dialogs: it
accepts new error mode and returns old error mode.
The error mode is process-global and automatically inherited to child
process when created.
MSYS2 bash shell internally sets it to not show error dialogs, therefore
`make check-stage#-rpass` should not show them either.
However, [1] says that `CreateProcess()` internally invokes
`SetErrorMode()` twice: at first it sets mode `0x8001` and saves
original mode, and at second it restores original mode.
So if two threads simultaneously call `CreateProcess()`, the first
thread sets error mode to `0x8001` then the second thread recognizes
that current error mode is `0x8001`. Therefore, The second thread will
create process with wrong error mode.
This really occurs inside `compiletest`: it creates several processes on
each thread, so some `run-pass` tests are invoked with wrong error mode
therefore show crash dialog.
This commit adds `StaticMutex` for `CreateProcess()` call. This seems
to fix the "dialog annoyance" issue.
[0]: http://support.microsoft.com/kb/315939
[1]: https://code.google.com/p/nativeclient/issues/detail?id=2968
[2]: https://ghc.haskell.org/trac/ghc/ticket/2650
This commit takes a first pass at stabilizing `std::thread`:
* It removes the `detach` method in favor of two constructors -- `spawn`
for detached threads, `scoped` for "scoped" (i.e., must-join)
threads. This addresses some of the surprise/frustrating debug
sessions with the previous API, in which `spawn` produced a guard that
on destruction joined the thread (unless `detach` was called).
The reason to have the division in part is that `Send` will soon not
imply `'static`, which means that `scoped` thread creation can take a
closure over *shared stack data* of the parent thread. On the other
hand, this means that the parent must not pop the relevant stack
frames while the child thread is running. The `JoinGuard` is used to
prevent this from happening by joining on drop (if you have not
already explicitly `join`ed.) The APIs around `scoped` are
future-proofed for the `Send` changes by taking an additional lifetime
parameter. With the current definition of `Send`, this is forced to be
`'static`, but when `Send` changes these APIs will gain their full
flexibility immediately.
Threads that are `spawn`ed, on the other hand, are detached from the
start and do not yield an RAII guard.
The hope is that, by making `scoped` an explicit opt-in with a very
suggestive name, it will be drastically less likely to be caught by a
surprising deadlock due to an implicit join at the end of a scope.
* The module itself is marked stable.
* Existing methods other than `spawn` and `scoped` are marked stable.
The migration path is:
```rust
Thread::spawn(f).detached()
```
becomes
```rust
Thread::spawn(f)
```
while
```rust
let res = Thread::spawn(f);
res.join()
```
becomes
```rust
let res = Thread::scoped(f);
res.join()
```
[breaking-change]