]> gitweb.factorcode.org Git - factor.git/commitdiff
More robust duplex stream
authorslava <slava@factorcode.org>
Fri, 28 Apr 2006 04:03:10 +0000 (04:03 +0000)
committerslava <slava@factorcode.org>
Fri, 28 Apr 2006 04:03:10 +0000 (04:03 +0000)
library/io/duplex-stream.factor

index 9d296be3f76418f7c3417b8f09a99a7a1d42b83f..58e2636cc387268a6e498da5cc6bdd43670ed297 100644 (file)
@@ -1,44 +1,64 @@
 ! Copyright (C) 2005 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 IN: io
-USING: kernel ;
+USING: errors kernel ;
 
-TUPLE: duplex-stream in out ;
+! We ensure that the stream can only be closed once, to preserve
+! integrity of duplex I/O ports.
+
+TUPLE: duplex-stream in out closed? ;
+
+C: duplex-stream ( in out -- stream )
+    [ set-duplex-stream-out ] keep
+    [ set-duplex-stream-in ] keep ;
+
+: check-closed ( duplex -- )
+    duplex-stream-closed?
+    [ "Duplex stream closed" throw ] when ;
+
+: duplex-stream-in+ ( duplex -- stream )
+    dup check-closed duplex-stream-in ;
+
+: duplex-stream-out+ ( duplex -- stream )
+    dup check-closed duplex-stream-out ;
 
 M: duplex-stream stream-flush
-    duplex-stream-out stream-flush ;
+    duplex-stream-out+ stream-flush ;
 
 M: duplex-stream stream-readln
-    duplex-stream-in stream-readln ;
+    duplex-stream-in+ stream-readln ;
 
 M: duplex-stream stream-read1
-    duplex-stream-in stream-read1 ;
+    duplex-stream-in+ stream-read1 ;
 
 M: duplex-stream stream-read
-    duplex-stream-in stream-read ;
+    duplex-stream-in+ stream-read ;
 
 M: duplex-stream stream-write1
-    duplex-stream-out stream-write1 ;
+    duplex-stream-out+ stream-write1 ;
 
 M: duplex-stream stream-write
-    duplex-stream-out stream-write ;
+    duplex-stream-out+ stream-write ;
 
 M: duplex-stream stream-terpri
-    duplex-stream-out stream-terpri ;
+    duplex-stream-out+ stream-terpri ;
 
 M: duplex-stream stream-format
-    duplex-stream-out stream-format ;
+    duplex-stream-out+ stream-format ;
 
 M: duplex-stream with-nested-stream
-    duplex-stream-out with-nested-stream ;
+    duplex-stream-out+ with-nested-stream ;
 
 M: duplex-stream stream-close
     #! The output stream is closed first, in case both streams
     #! are attached to the same file descriptor, the output
     #! buffer needs to be flushed before we close the fd.
-    dup
-    duplex-stream-out stream-close
-    duplex-stream-in stream-close ;
+    dup duplex-stream-closed? [
+        t over set-duplex-stream-closed?
+        dup
+        duplex-stream-out stream-close
+        duplex-stream-in stream-close
+    ] unless ;
 
 M: duplex-stream set-timeout
     2dup