about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorSimonas Kazlauskas <git@kazlauskas.me>2015-04-04 00:46:54 +0300
committerSimonas Kazlauskas <git@kazlauskas.me>2015-04-08 19:42:16 +0300
commit45aa6c8d1bc2f7863c92da6643de4642bb2d83bf (patch)
tree53f8648a696dc49072ceef53c36974f6fc599515 /src/test
parent80def6c2447d23a624e611417f24cf0ab2a5a676 (diff)
downloadrust-45aa6c8d1bc2f7863c92da6643de4642bb2d83bf.tar.gz
rust-45aa6c8d1bc2f7863c92da6643de4642bb2d83bf.zip
Implement reentrant mutexes and make stdio use them
write_fmt calls write for each formatted field. The default implementation of write_fmt is used,
which will call write on not-yet-locked stdout (and write locking after), therefore making print!
in multithreaded environment still interleave contents of two separate prints.

This patch implements reentrant mutexes, changes stdio handles to use these mutexes and overrides
write_fmt to lock the stdio handle for the whole duration of the call.
Diffstat (limited to 'src/test')
-rw-r--r--src/test/run-pass/atomic-print.rs48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/test/run-pass/atomic-print.rs b/src/test/run-pass/atomic-print.rs
new file mode 100644
index 00000000000..df3b572bce4
--- /dev/null
+++ b/src/test/run-pass/atomic-print.rs
@@ -0,0 +1,48 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::{env, fmt, process, sync, thread};
+
+struct SlowFmt(u32);
+impl fmt::Debug for SlowFmt {
+    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+        thread::sleep_ms(3);
+        self.0.fmt(f)
+    }
+}
+
+fn do_print(x: u32) {
+    let x = SlowFmt(x);
+    println!("{:?}{:?}{:?}{:?}{:?}", x, x, x, x, x);
+}
+
+fn main(){
+    if env::args().count() == 2 {
+        let barrier = sync::Arc::new(sync::Barrier::new(2));
+        let tbarrier = barrier.clone();
+        let t = thread::scoped(||{
+            tbarrier.wait();
+            do_print(1);
+        });
+        barrier.wait();
+        do_print(2);
+        t.join();
+    } else {
+        let this = env::args().next().unwrap();
+        let output = process::Command::new(this).arg("-").output().unwrap();
+        for line in String::from_utf8(output.stdout).unwrap().lines() {
+            match line.chars().next().unwrap() {
+                '1' => assert_eq!(line, "11111"),
+                '2' => assert_eq!(line, "22222"),
+                _   => panic!("Unexpected character")
+            }
+        }
+    }
+}