[m-rev.] for review: stream typeclasses
Julien Fischer
juliensf at csse.unimelb.edu.au
Wed Oct 25 13:35:37 AEST 2006
On Mon, 23 Oct 2006, Peter Ross wrote:
> I think streams should support non-blocking I/O as well.
> I can't forsee any problems due to the current hierachy of typeclasses
> to supporting non-blocking I/O, but I haven't thought about it deeply.
> Have you?
The following diff adds support for non-blocking streams (however
see the XXX on the non-blocking version of put).
Comments?
Index: stream.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/Attic/stream.m,v
retrieving revision 1.1.2.11
diff -u -r1.1.2.11 stream.m
--- stream.m 23 Oct 2006 02:28:43 -0000 1.1.2.11
+++ stream.m 25 Oct 2006 03:32:59 -0000
@@ -14,7 +14,6 @@
% on instances of these typeclasses.
%
% TODO:
-% * Add non-blocking versions of the stream operations.
% * Thread-safety aspects(?)
% * Add a typeclass to hold the offset method for binary input streams.
%
@@ -29,16 +28,50 @@
%-----------------------------------------------------------------------------%
%
-% Stream errors
+% Types used by streams
%
:- type stream.name == string.
+ % Values of this type are returned by the get and non_blocking_get
+ % methods.
+ %
:- type stream.result(T, Error)
---> ok(T)
; eof
+ ; unavailable
; error(Error).
+ % The blocking version of get will never return unavailable.
+ %
+:- inst stream.blocking_get_result
+ ---> ok(ground)
+ ; eof
+ ; error(ground).
+
+ % Non-blocking output streams return values of this type to indicate
+ % whether a put operation was successful.
+ %
+:- type stream.non_blocking_put_result
+ ---> ok
+ ; unavailable.
+
+:- type stream.res(Error)
+ ---> ok
+ ; error(Error).
+
+ % stream.maybe_partial_res is used when it is possible to return
+ % a partial result when an error occurs.
+ %
+:- type stream.maybe_partial_res(T, Error)
+ ---> ok(T)
+ ; error(T, Error).
+
+%-----------------------------------------------------------------------------%
+%
+% Stream errors
+%
+
:- typeclass stream.error(Error) where
[
@@ -84,7 +117,7 @@
% A reader stream is a subclass of specific input stream that can be
% used to read data of a specific type from the input stream.
- % A single input streams can support multiple reader subclasses.
+ % A single input stream can support multiple reader subclasses.
%
:- typeclass stream.reader(Stream, Unit, State, Error)
<= stream.input(Stream, State, Error) where
@@ -92,7 +125,18 @@
% Get the next unit from the given stream.
% The get operation should block until the next unit is available.
%
- pred get(Stream::in, stream.result(Unit, Error)::out,
+ pred get(Stream::in, stream.result(Unit, Error)::out(blocking_get_result),
+ State::di, State::uo) is det
+].
+
+:- typeclass stream.non_blocking_reader(Stream, Unit, State, Error)
+ <= stream.input(Stream, State, Error) where
+[
+
+ % Get the next unit from the given stream.
+ % Returns `unavailable' if the stream would have blocked.
+ %
+ pred non_blocking_get(Stream::in, stream.result(Unit, Error)::out,
State::di, State::uo) is det
].
@@ -104,7 +148,7 @@
% An output stream is a destination for data.
% Note that unlike input streams, output stream do not include
% an explicit error type. They should handle errors by throwing
- % a exceptions.
+ % exceptions.
%
:- typeclass stream.output(Stream, State)
<= stream(Stream, State) where
@@ -115,8 +159,8 @@
pred flush(Stream::in, State::di, State::uo) is det
].
- % A writer stream is a subclass of specific output stream that can be
- % used to write data of a specific type to the output stream.
+ % A writer stream is a subclass of a specific output stream that can
+ % be used to write data of a specific type to the output stream.
% A single output stream can support multiple writer subclasses.
%
:- typeclass stream.writer(Stream, Unit, State)
@@ -128,6 +172,24 @@
pred put(Stream::in, Unit::in, State::di, State::uo) is det
].
+ % A non_blocking_writer stream is a subclass of a specific output stream
+ % that can be used to write data of specific type to the output stream
+ % in a non-blocking fahsion.
+ %
+:- typeclass stream.non_blocking_writer(Stream, Unit, State)
+ <= stream.output(Stream, State) where
+[
+ % Write the next unit to the given stream.
+ % Returns `ok' if the write was completed and returns `unavailable'
+ % if the stream would have blocked.
+ % XXX Should/can we make any guarantees about the atomicity of writes?
+ % If not should/how do we return details if the unit was only
+ % partially written?
+ %
+ pred non_blocking_put(Stream::in, Unit::in,
+ stream.non_blocking_put_result::out, State::di, State::uo) is det
+].
+
%-----------------------------------------------------------------------------%
%
% Duplex streams
@@ -212,20 +274,9 @@
%-----------------------------------------------------------------------------%
%
-% Generic folds over input streams
+% Generic folds over blocking input streams
%
-:- type stream.res(Error)
- ---> ok
- ; error(Error).
-
- % stream.maybe_partial_res is used when it is possible to return
- % a partial result when an error occurs.
- %
-:- type stream.maybe_partial_res(T, Error)
- ---> ok(T)
- ; error(T, Error).
-
% Applies the given closure to each Unit read from the input stream
% in turn, until eof or error.
%
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list