Skip to content

Commit d567d95

Browse files
authored
Rollup merge of rust-lang#93965 - Mark-Simulacrum:owned-stdio, r=dtolnay
Make regular stdio lock() return 'static handles This also deletes the unstable API surface area previously added to expose this functionality on new methods rather than built into the current set. Closes rust-lang#86845 (tracking issue for unstable API needed without this) r? ````@dtolnay```` to kick off T-libs-api FCP
2 parents 0a67c2f + 398cccd commit d567d95

File tree

3 files changed

+18
-228
lines changed

3 files changed

+18
-228
lines changed

library/std/src/io/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,6 @@ pub use self::buffered::WriterPanicked;
268268
pub use self::stdio::set_output_capture;
269269
#[unstable(feature = "print_internals", issue = "none")]
270270
pub use self::stdio::{_eprint, _print};
271-
#[unstable(feature = "stdio_locked", issue = "86845")]
272-
pub use self::stdio::{stderr_locked, stdin_locked, stdout_locked};
273271
#[stable(feature = "rust1", since = "1.0.0")]
274272
pub use self::{
275273
buffered::{BufReader, BufWriter, IntoInnerError, LineWriter},

library/std/src/io/stdio.rs

+15-223
Original file line numberDiff line numberDiff line change
@@ -307,48 +307,6 @@ pub fn stdin() -> Stdin {
307307
}
308308
}
309309

310-
/// Constructs a new locked handle to the standard input of the current
311-
/// process.
312-
///
313-
/// Each handle returned is a guard granting locked access to a shared
314-
/// global buffer whose access is synchronized via a mutex. If you need
315-
/// more explicit control over locking, for example, in a multi-threaded
316-
/// program, use the [`io::stdin`] function to obtain an unlocked handle,
317-
/// along with the [`Stdin::lock`] method.
318-
///
319-
/// The lock is released when the returned guard goes out of scope. The
320-
/// returned guard also implements the [`Read`] and [`BufRead`] traits for
321-
/// accessing the underlying data.
322-
///
323-
/// **Note**: The mutex locked by this handle is not reentrant. Even in a
324-
/// single-threaded program, calling other code that accesses [`Stdin`]
325-
/// could cause a deadlock or panic, if this locked handle is held across
326-
/// that call.
327-
///
328-
/// ### Note: Windows Portability Consideration
329-
/// When operating in a console, the Windows implementation of this stream does not support
330-
/// non-UTF-8 byte sequences. Attempting to read bytes that are not valid UTF-8 will return
331-
/// an error.
332-
///
333-
/// # Examples
334-
///
335-
/// ```no_run
336-
/// #![feature(stdio_locked)]
337-
/// use std::io::{self, BufRead};
338-
///
339-
/// fn main() -> io::Result<()> {
340-
/// let mut buffer = String::new();
341-
/// let mut handle = io::stdin_locked();
342-
///
343-
/// handle.read_line(&mut buffer)?;
344-
/// Ok(())
345-
/// }
346-
/// ```
347-
#[unstable(feature = "stdio_locked", issue = "86845")]
348-
pub fn stdin_locked() -> StdinLock<'static> {
349-
stdin().into_locked()
350-
}
351-
352310
impl Stdin {
353311
/// Locks this handle to the standard input stream, returning a readable
354312
/// guard.
@@ -372,8 +330,10 @@ impl Stdin {
372330
/// }
373331
/// ```
374332
#[stable(feature = "rust1", since = "1.0.0")]
375-
pub fn lock(&self) -> StdinLock<'_> {
376-
self.lock_any()
333+
pub fn lock(&self) -> StdinLock<'static> {
334+
// Locks this handle with 'static lifetime. This depends on the
335+
// implementation detail that the underlying `Mutex` is static.
336+
StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
377337
}
378338

379339
/// Locks this handle and reads a line of input, appending it to the specified buffer.
@@ -407,43 +367,6 @@ impl Stdin {
407367
self.lock().read_line(buf)
408368
}
409369

410-
// Locks this handle with any lifetime. This depends on the
411-
// implementation detail that the underlying `Mutex` is static.
412-
fn lock_any<'a>(&self) -> StdinLock<'a> {
413-
StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
414-
}
415-
416-
/// Consumes this handle to the standard input stream, locking the
417-
/// shared global buffer associated with the stream and returning a
418-
/// readable guard.
419-
///
420-
/// The lock is released when the returned guard goes out of scope. The
421-
/// returned guard also implements the [`Read`] and [`BufRead`] traits
422-
/// for accessing the underlying data.
423-
///
424-
/// It is often simpler to directly get a locked handle using the
425-
/// [`stdin_locked`] function instead, unless nearby code also needs to
426-
/// use an unlocked handle.
427-
///
428-
/// # Examples
429-
///
430-
/// ```no_run
431-
/// #![feature(stdio_locked)]
432-
/// use std::io::{self, BufRead};
433-
///
434-
/// fn main() -> io::Result<()> {
435-
/// let mut buffer = String::new();
436-
/// let mut handle = io::stdin().into_locked();
437-
///
438-
/// handle.read_line(&mut buffer)?;
439-
/// Ok(())
440-
/// }
441-
/// ```
442-
#[unstable(feature = "stdio_locked", issue = "86845")]
443-
pub fn into_locked(self) -> StdinLock<'static> {
444-
self.lock_any()
445-
}
446-
447370
/// Consumes this handle and returns an iterator over input lines.
448371
///
449372
/// For detailed semantics of this method, see the documentation on
@@ -463,7 +386,7 @@ impl Stdin {
463386
#[must_use = "`self` will be dropped if the result is not used"]
464387
#[unstable(feature = "stdin_forwarders", issue = "87096")]
465388
pub fn lines(self) -> Lines<StdinLock<'static>> {
466-
self.into_locked().lines()
389+
self.lock().lines()
467390
}
468391
}
469392

@@ -649,42 +572,6 @@ pub fn stdout() -> Stdout {
649572
}
650573
}
651574

652-
/// Constructs a new locked handle to the standard output of the current
653-
/// process.
654-
///
655-
/// Each handle returned is a guard granting locked access to a shared
656-
/// global buffer whose access is synchronized via a mutex. If you need
657-
/// more explicit control over locking, for example, in a multi-threaded
658-
/// program, use the [`io::stdout`] function to obtain an unlocked handle,
659-
/// along with the [`Stdout::lock`] method.
660-
///
661-
/// The lock is released when the returned guard goes out of scope. The
662-
/// returned guard also implements the [`Write`] trait for writing data.
663-
///
664-
/// ### Note: Windows Portability Consideration
665-
/// When operating in a console, the Windows implementation of this stream does not support
666-
/// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
667-
/// an error.
668-
///
669-
/// # Examples
670-
///
671-
/// ```no_run
672-
/// #![feature(stdio_locked)]
673-
/// use std::io::{self, Write};
674-
///
675-
/// fn main() -> io::Result<()> {
676-
/// let mut handle = io::stdout_locked();
677-
///
678-
/// handle.write_all(b"hello world")?;
679-
///
680-
/// Ok(())
681-
/// }
682-
/// ```
683-
#[unstable(feature = "stdio_locked", issue = "86845")]
684-
pub fn stdout_locked() -> StdoutLock<'static> {
685-
stdout().into_locked()
686-
}
687-
688575
pub fn cleanup() {
689576
if let Some(instance) = STDOUT.get() {
690577
// Flush the data and disable buffering during shutdown
@@ -712,55 +599,20 @@ impl Stdout {
712599
/// use std::io::{self, Write};
713600
///
714601
/// fn main() -> io::Result<()> {
715-
/// let stdout = io::stdout();
716-
/// let mut handle = stdout.lock();
602+
/// let mut stdout = io::stdout().lock();
717603
///
718-
/// handle.write_all(b"hello world")?;
604+
/// stdout.write_all(b"hello world")?;
719605
///
720606
/// Ok(())
721607
/// }
722608
/// ```
723609
#[stable(feature = "rust1", since = "1.0.0")]
724-
pub fn lock(&self) -> StdoutLock<'_> {
725-
self.lock_any()
726-
}
727-
728-
// Locks this handle with any lifetime. This depends on the
729-
// implementation detail that the underlying `ReentrantMutex` is
730-
// static.
731-
fn lock_any<'a>(&self) -> StdoutLock<'a> {
610+
pub fn lock(&self) -> StdoutLock<'static> {
611+
// Locks this handle with 'static lifetime. This depends on the
612+
// implementation detail that the underlying `ReentrantMutex` is
613+
// static.
732614
StdoutLock { inner: self.inner.lock() }
733615
}
734-
735-
/// Consumes this handle to the standard output stream, locking the
736-
/// shared global buffer associated with the stream and returning a
737-
/// writable guard.
738-
///
739-
/// The lock is released when the returned lock goes out of scope. The
740-
/// returned guard also implements the [`Write`] trait for writing data.
741-
///
742-
/// It is often simpler to directly get a locked handle using the
743-
/// [`io::stdout_locked`] function instead, unless nearby code also
744-
/// needs to use an unlocked handle.
745-
///
746-
/// # Examples
747-
///
748-
/// ```no_run
749-
/// #![feature(stdio_locked)]
750-
/// use std::io::{self, Write};
751-
///
752-
/// fn main() -> io::Result<()> {
753-
/// let mut handle = io::stdout().into_locked();
754-
///
755-
/// handle.write_all(b"hello world")?;
756-
///
757-
/// Ok(())
758-
/// }
759-
/// ```
760-
#[unstable(feature = "stdio_locked", issue = "86845")]
761-
pub fn into_locked(self) -> StdoutLock<'static> {
762-
self.lock_any()
763-
}
764616
}
765617

766618
#[stable(feature = "std_debug", since = "1.16.0")]
@@ -935,35 +787,6 @@ pub fn stderr() -> Stderr {
935787
}
936788
}
937789

938-
/// Constructs a new locked handle to the standard error of the current
939-
/// process.
940-
///
941-
/// This handle is not buffered.
942-
///
943-
/// ### Note: Windows Portability Consideration
944-
/// When operating in a console, the Windows implementation of this stream does not support
945-
/// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
946-
/// an error.
947-
///
948-
/// # Example
949-
///
950-
/// ```no_run
951-
/// #![feature(stdio_locked)]
952-
/// use std::io::{self, Write};
953-
///
954-
/// fn main() -> io::Result<()> {
955-
/// let mut handle = io::stderr_locked();
956-
///
957-
/// handle.write_all(b"hello world")?;
958-
///
959-
/// Ok(())
960-
/// }
961-
/// ```
962-
#[unstable(feature = "stdio_locked", issue = "86845")]
963-
pub fn stderr_locked() -> StderrLock<'static> {
964-
stderr().into_locked()
965-
}
966-
967790
impl Stderr {
968791
/// Locks this handle to the standard error stream, returning a writable
969792
/// guard.
@@ -986,43 +809,12 @@ impl Stderr {
986809
/// }
987810
/// ```
988811
#[stable(feature = "rust1", since = "1.0.0")]
989-
pub fn lock(&self) -> StderrLock<'_> {
990-
self.lock_any()
991-
}
992-
993-
// Locks this handle with any lifetime. This depends on the
994-
// implementation detail that the underlying `ReentrantMutex` is
995-
// static.
996-
fn lock_any<'a>(&self) -> StderrLock<'a> {
812+
pub fn lock(&self) -> StderrLock<'static> {
813+
// Locks this handle with 'static lifetime. This depends on the
814+
// implementation detail that the underlying `ReentrantMutex` is
815+
// static.
997816
StderrLock { inner: self.inner.lock() }
998817
}
999-
1000-
/// Locks and consumes this handle to the standard error stream,
1001-
/// returning a writable guard.
1002-
///
1003-
/// The lock is released when the returned guard goes out of scope. The
1004-
/// returned guard also implements the [`Write`] trait for writing
1005-
/// data.
1006-
///
1007-
/// # Examples
1008-
///
1009-
/// ```
1010-
/// #![feature(stdio_locked)]
1011-
/// use std::io::{self, Write};
1012-
///
1013-
/// fn foo() -> io::Result<()> {
1014-
/// let stderr = io::stderr();
1015-
/// let mut handle = stderr.into_locked();
1016-
///
1017-
/// handle.write_all(b"hello world")?;
1018-
///
1019-
/// Ok(())
1020-
/// }
1021-
/// ```
1022-
#[unstable(feature = "stdio_locked", issue = "86845")]
1023-
pub fn into_locked(self) -> StderrLock<'static> {
1024-
self.lock_any()
1025-
}
1026818
}
1027819

1028820
#[stable(feature = "std_debug", since = "1.16.0")]

library/std/src/io/stdio/tests.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,17 @@ fn panic_doesnt_poison() {
5050
#[test]
5151
#[cfg_attr(target_os = "emscripten", ignore)]
5252
fn test_lock_stderr() {
53-
test_lock(stderr, stderr_locked);
53+
test_lock(stderr, || stderr().lock());
5454
}
5555
#[test]
5656
#[cfg_attr(target_os = "emscripten", ignore)]
5757
fn test_lock_stdin() {
58-
test_lock(stdin, stdin_locked);
58+
test_lock(stdin, || stdin().lock());
5959
}
6060
#[test]
6161
#[cfg_attr(target_os = "emscripten", ignore)]
6262
fn test_lock_stdout() {
63-
test_lock(stdout, stdout_locked);
63+
test_lock(stdout, || stdout().lock());
6464
}
6565

6666
// Helper trait to make lock testing function generic.

0 commit comments

Comments
 (0)