rust/library/std/src/io
bors 8cef65fde3 Auto merge of #77801 - fusion-engineering-forks:pin-mutex, r=Mark-Simulacrum
Enforce no-move rule of ReentrantMutex using Pin and fix UB in stdio

A `sys_common::ReentrantMutex` may not be moved after initializing it with `.init()`. This was not enforced, but only stated as a requirement in the comments on the unsafe functions. This change enforces this no-moving rule using `Pin`, by changing `&self` to a `Pin` in the `init()` and `lock()` functions.

This uncovered a bug I introduced in #77154: stdio.rs (the only user of ReentrantMutex) called `init()` on its ReentrantMutexes while constructing them in the intializer of `SyncOnceCell::get_or_init`, which would move them afterwards. Interestingly, the ReentrantMutex unit tests already had the same bug, so this invalid usage has been tested on all (CI-tested) platforms for a long time. Apparently this doesn't break badly on any of the major platforms, but it does break the rules.\*

To be able to keep using SyncOnceCell, this adds a `SyncOnceCell::get_or_init_pin` function, which makes it possible to work with pinned values inside a (pinned) SyncOnceCell. Whether this function should be public or not and what its exact behaviour and interface should be if it would be public is something I'd like to leave for a separate issue or PR. In this PR, this function is internal-only and marked with `pub(crate)`.

\* Note: That bug is now included in 1.48, while this patch can only make it to ~~1.49~~ 1.50. We should consider the implications of 1.48 shipping with a wrong usage of `pthread_mutex_t` / `CRITICAL_SECTION` / .. which technically invokes UB according to their specification. The risk is very low, considering the objects are not 'used' (locked) before the move, and the ReentrantMutex unit tests have verified this works fine in practice.

Edit: This has been backported and included in 1.48. And soon 1.49 too.

---

In future changes, I want to push this usage of Pin further inside `sys` instead of only `sys_common`, and apply it to all 'unmovable' objects there (`Mutex`, `Condvar`, `RwLock`). Also, while `sys_common`'s mutexes and condvars are already taken care of by #77147 and #77648, its `RwLock` should still be made movable or get pinned.
2020-12-10 23:43:20 +00:00
..
buffered Auto merge of #78768 - mzabaluev:optimize-buf-writer, r=cramertj 2020-12-09 01:54:08 +00:00
cursor Make some std::io functions const 2020-11-06 17:48:26 +01:00
error std: move "mod tests/benches" to separate files 2020-08-31 02:56:59 +00:00
impls std: move "mod tests/benches" to separate files 2020-08-31 02:56:59 +00:00
stdio std: move "mod tests/benches" to separate files 2020-08-31 02:56:59 +00:00
util Make some std::io functions const 2020-11-06 17:48:26 +01:00
copy.rs limit visibility of copy offload helpers to sys::unix module 2020-11-13 22:38:27 +01:00
cursor.rs Add tracking issue 2020-11-06 18:04:52 +01:00
error.rs std: move "mod tests/benches" to separate files 2020-08-31 02:56:59 +00:00
impls.rs std: impl of Write for &mut [u8]: document the buffer full error 2020-12-04 18:38:44 +00:00
mod.rs Fix typo in std::io::Write docs 2020-11-17 15:32:23 -08:00
prelude.rs mv std libs to library/ 2020-07-27 19:51:13 -05:00
stdio.rs Use Pin for the 'don't move' requirement of ReentrantMutex. 2020-12-08 22:57:57 +01:00
tests.rs move copy specialization tests to their own module 2020-11-13 22:38:27 +01:00
util.rs Auto merge of #75272 - the8472:spec-copy, r=KodrAus 2020-11-14 12:01:55 +00:00