When the timer_helper thread exited, it would attempt to re-acquire the global
task count mutex, but the mutex had previously been deallocated, leading to
undefined behavior of the mutex, and in some cases deadlock.
Another mutex is used to coordinate shutting down the timer helper thread.
Closes#12699
Using nanosleep() allows us to gracefully recover from EINTR because on error it
fills in the second parameter with the remaining time to sleep.
Closes#12689
- Added `TraitObject` representation to `std::raw`.
- Added doc to `std::raw`.
- Removed `Any::as_void_ptr()` and `Any::as_mut_void_ptr()`
methods as they are uneccessary now after the removal of
headers on owned boxes. This reduces the number of virtual calls needed from 2 to 1.
- Made the `..Ext` implementations work directly with the repr of
a trait object.
- Removed `Any`-related traits from the prelude.
- Added bench.
Bench before/after:
~~~
7 ns/iter (+/- 0)
4 ns/iter (+/- 0)
~~~
- Added `TraitObject` representation to `std::raw`.
- Added doc to `std::raw`.
- Removed `Any::as_void_ptr()` and `Any::as_mut_void_ptr()`
methods as they are uneccessary now after the removal of
headers on owned boxes. This reduces the number of virtual calls needed.
- Made the `..Ext` implementations work directly with the repr of
a trait object.
- Removed `Any`-related traits from the prelude.
- Added bench for `Any`
I've been playing around with code size when linking to libstd recently, and these were some findings I found that really helped code size. I started out by eliminating all I/O implementations from libnative and instead just return an unimplemented error.
In doing so, a `fn main() {}` executable was ~378K before this patch, and about 170K after the patch. These size wins are all pretty minor, but they all seemed pretty reasonable to me. With native I/O not stubbed out, this takes the size of an LTO executable from 675K to 400K.
This removes all usage of Poly in format strings from libstd. This doesn't
prevent more future strings from coming in, but it at least removes the ones for
now.
There's a lot of these types in the compiler libraries, and a few of the
older or private stdlib ones. Some types are obviously meant to be
public, others not so much.
The compiler itself doesn't necessarily need any features of green threading
such as spawning tasks and lots of I/O, so libnative is slightly more
appropriate for rustc to use itself.
This should also help the rusti bot which is currently incompatible with libuv.
This commit splits the file implementation into file_unix and file_win32. The
two implementations have diverged to the point that they share almost 0 code at
this point, so it's easier to maintain as separate files.
The other major change accompanied with this commit is that file::open is no
longer based on libc's open function on windows, but rather windows's CreateFile
function. This fixes dealing with binary files on windows (test added in
previous commit).
This also changes the read/write functions to use ReadFile and WriteFile instead
of libc's read/write.
Closes#12406
Commits for details. Highlights:
- `flate` returns `CVec<u8>` to save reallocating a whole new `&[u8]`
- a lot of `transmute`s removed outright or replaced with `as` (etc.)
The std::run module is a relic from a standard library long since past, and
there's not much use to having two modules to execute processes with where one
is slightly more convenient. This commit merges the two modules, moving lots of
functionality from std::run into std::io::process and then deleting
std::run.
New things you can find in std::io::process are:
* Process::new() now only takes prog/args
* Process::configure() takes a ProcessConfig
* Process::status() is the same as run::process_status
* Process::output() is the same as run::process_output
* I/O for spawned tasks is now defaulted to captured in pipes instead of ignored
* Process::kill() was added (plus an associated green/native implementation)
* Process::wait_with_output() is the same as the old finish_with_output()
* destroy() is now signal_exit()
* force_destroy() is now signal_kill()
Closes#2625Closes#10016
With the stability attributes we can put public-but unstable modules next to others, so this moves `intrinsics` and `raw` out of the `unstable` module (and marks both as `#[experimental]`).
These two containers are indeed collections, so their place is in
libcollections, not in libstd. There will always be a hash map as part of the
standard distribution of Rust, but by moving it out of the standard library it
makes libstd that much more portable to more platforms and environments.
This conveniently also removes the stuttering of 'std::hashmap::HashMap',
although 'collections::HashMap' is only one character shorter.
Added allow(non_camel_case_types) to librustc where necesary
Tried to fix problems with non_camel_case_types outside rustc
fixed failing tests
Docs updated
Moved #[allow(non_camel_case_types)] a level higher.
markdown.rs reverted
Fixed timer that was failing tests
Fixed another timer
This "bubble up an error" macro was originally named if_ok! in order to get it
landed, but after the fact it was discovered that this name is not exactly
desirable.
The name `if_ok!` isn't immediately clear that is has much to do with error
handling, and it doesn't look fantastic in all contexts (if if_ok!(...) {}). In
general, the agreed opinion about `if_ok!` is that is came in as subpar.
The name `try!` is more invocative of error handling, it's shorter by 2 letters,
and it looks fitting in almost all circumstances. One concern about the word
`try!` is that it's too invocative of exceptions, but the belief is that this
will be overcome with documentation and examples.
Close#12037
Iterators! Use them (in `is_utf16`), create them (in `utf16_items`).
Handle errors gracefully (`from_utf16_lossy`) and `from_utf16` returning `Option<~str>` instead of failing.
Add a pile of tests.
Many of the functions interacting with Windows APIs allocate a vector of
0's and do not retrieve a length directly from the API call, and so need
to be sure to remove the unmodified junk at the end of the vector.
There's a few parts to this PR
* Implement unix pipes in libnative for unix platforms (thanks @Geal!)
* Implement named pipes in libnative for windows (terrible, terrible code)
* Remove `#[cfg(unix)]` from `mod unix` in `std::io::net`. This is a terrible name for what it is, but that's the topic of #12093.
The windows implementation was significantly more complicated than I thought it would be, but it seems to be passing all the tests. now.
Closes#11201
Delete all the documentation from std::task that references linked
failure.
Tweak TaskBuilder to be more builder-like. `.name()` is now `.named()` and
`.add_wrapper()` is now `.with_wrapper()`. Remove `.watched()` and
`.unwatched()` as they didn't actually do anything.
Closes#6399.
* Implementation of pipe_win32 filled out for libnative
* Reorganize pipes to be clone-able
* Fix a few file descriptor leaks on error
* Factor out some common code into shared functions
* Make use of the if_ok!() macro for less indentation
Closes#11201
Delete all the documentation from std::task that references linked
failure.
Tweak TaskBuilder to be more builder-like. .name() is now .named() and
.add_wrapper() is now .with_wrapper(). Remove .watched() and
.unwatched() as they didn't actually do anything.
- adds a `LockGuard` type returned by `.lock` and `.trylock` that unlocks the mutex in the destructor
- renames `mutex::Mutex` to `StaticNativeMutex`
- adds a `NativeMutex` type with a destructor
- removes `LittleLock`
- adds `#[must_use]` to `sync::mutex::Guard` to remind people to use it
Instead, use an enum to allow running both a procedure and sending the task
result over a channel. I expect the common case to be sending on a channel (e.g.
task::try), so don't require an extra allocation in the common case.
cc #11389
This, the Nth rewrite of channels, is not a rewrite of the core logic behind
channels, but rather their API usage. In the past, we had the distinction
between oneshot, stream, and shared channels, but the most recent rewrite
dropped oneshots in favor of streams and shared channels.
This distinction of stream vs shared has shown that it's not quite what we'd
like either, and this moves the `std::comm` module in the direction of "one
channel to rule them all". There now remains only one Chan and one Port.
This new channel is actually a hybrid oneshot/stream/shared channel under the
hood in order to optimize for the use cases in question. Additionally, this also
reduces the cognitive burden of having to choose between a Chan or a SharedChan
in an API.
My simple benchmarks show no reduction in efficiency over the existing channels
today, and a 3x improvement in the oneshot case. I sadly don't have a
pre-last-rewrite compiler to test out the old old oneshots, but I would imagine
that the performance is comparable, but slightly slower (due to atomic reference
counting).
This commit also brings the bonus bugfix to channels that the pending queue of
messages are all dropped when a Port disappears rather then when both the Port
and the Chan disappear.
Declare a `type SendStr = MaybeOwned<'static>` to ease readibility of
types that needed the old SendStr behavior.
Implement all the traits for MaybeOwned that SendStr used to implement.
This is part of the overall strategy I would like to take when approaching
issue #11165. The only two I/O objects that reasonably want to be "split" are
the network stream objects. Everything else can be "split" by just creating
another version.
The initial idea I had was the literally split the object into a reader and a
writer half, but that would just introduce lots of clutter with extra interfaces
that were a little unnnecssary, or it would return a ~Reader and a ~Writer which
means you couldn't access things like the remote peer name or local socket name.
The solution I found to be nicer was to just clone the stream itself. The clone
is just a clone of the handle, nothing fancy going on at the kernel level.
Conceptually I found this very easy to wrap my head around (everything else
supports clone()), and it solved the "split" problem at the same time.
The cloning support is pretty specific per platform/lib combination:
* native/win32 - uses some specific WSA apis to clone the SOCKET handle
* native/unix - uses dup() to get another file descriptor
* green/all - This is where things get interesting. When we support full clones
of a handle, this implies that we're allowing simultaneous writes
and reads to happen. It turns out that libuv doesn't support two
simultaneous reads or writes of the same object. It does support
*one* read and *one* write at the same time, however. Some extra
infrastructure was added to just block concurrent writers/readers
until the previous read/write operation was completed.
I've added tests to the tcp/unix modules to make sure that this functionality is
supported everywhere.