caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: "Vladimir N. Silyaev" <vsilyaev@mindspring.com>
To: Benjamin Geer <ben@socialtools.net>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] Re: Common IO structure
Date: Sat, 8 May 2004 00:29:22 -0700	[thread overview]
Message-ID: <20040508072922.GA2771@server.vns.oc.ca.us> (raw)
In-Reply-To: <409C0985.9060703@socialtools.net>

On Fri, May 07, 2004 at 11:11:17PM +0100, Benjamin Geer wrote:

> >This signature looks like a good starting point. However I would rather
> >separate this code to three different pieces
> 
> That seems fine to me.  I just wanted to give you a very rough idea of 
> what I had in mind; I was pretty sure you'd see a better way to design 
> it. :)
> 
> >Please note,  that write and read inherently separated in signatures,
> >it allows simpler interface, supports read/write only streams
> >and better feet common model, where read and writes are separated.
> >However, module couldn't implement both read and write signatures, if
> >it's required.
> 
> The main thing I wanted to point out was that there needs to be a way to 
> read data into a buffer from a non-blocking socket into a buffer, and 
> then write the data from the *same buffer* into another non-blocking 
> socket.  Then compact the buffer (move any unwritten data to the 
> beginning of the buffer) and start again, like in this loop:
> 
> let copy_fd in_fd out_fd =
>   let b = AsyncBuffer.create () in
>     try
>       while (true) do
>         AsyncBuffer.from_fd b in_fd;
>         AsyncBuffer.flip b;
>         AsyncBuffer.to_fd b out_fd;
>         AsyncBuffer.compact b
>       done
>     with End_of_file -> ()
> 
> Can that still be done if the read and write signatures are separated?
Surely, just a little twist:
module Block = struct
  module type NbRead = sig
    type t
    val nb_read:  t -> string -> int -> int -> int
  end
  module type NbWrite = sig
    type t
    val nb_write:  t -> string -> int -> int -> int
  end
end

Note, that both read or write are using supplied buffers, so zero
copy is possible.
module NbCopy (Src:Block.NbRead) (Dst:Block.NbWrite) = struct
  let run s d = 
   let blen = 4096 in
   let buf = String.create blen in
   let rec copy off = 
     let  off  = if off = blen then 0 else off in
     let  rlen = blen - off in
     let  n = Src.nb_read s buf off rlen in
     let  n = Dst.nb_write d buf off n in
     copy (off+n)
   in
   try copy 0 with
   End_of_file -> ()
end

> 
> The other thing that's important is that character encoder/decoders 
> would need to be able to read characters from one buffer and write them 
> to another buffer in a different encoding.  An encoder/decoder would 
> need to gracefully handle the case where it reads from a buffer 
> containing incomplete characters.  That's another reason for the 
> 'compact' function: you could read 10 bytes from a socket into a buffer, 
> and those 10 bytes could contain 9 bytes worth of complete UTF-8 
> characters; the 10th byte would be the first byte of a multi-byte 
> character.  You'd pass the buffer to an encoder/decoder, which would 
> read 9 bytes and write them into another buffer in a different encoding 
> (say UTF-16), leaving the last byte.  You would then call 'compact' to 
> move that byte to the beginning of the buffer, and repeat.
> 
> Is there a way to fit this approach into what you've proposed for 
> encoder/decoders?
That's more complicated. Basically what was initially proposed is for
blocking IO, where read (get) guaranteed to return result or fail,
and fail is terminal, filter is not required to support restart procedure.
This works for any type of blocking IO, however it fails for non blocking
IO where restart is common technique. Problem with restart, that it places
unbounded restrictions of filter, it should be able to handle incomplete
inputs and support backtracking.

However non blocking IO usually used as an alternative for threads, in which
case it might be beneficial just change control type and add support 
for non blocking IO into the signature by using explicit continuation 
passing. There is an example for get and put signature with CPS:
 val get: t -> (symbol -> unit) -> unit
 val put: t -> (unit -> unit) -> symbol -> unit

Advantage of using CPS style, is that state of the "filter" captured
by the compiler in a closure at the time of function application. Disadvantage
of CPS style is rather unusual look of code and cost of closure 
construction. Later could be significantly reduced by short circuiting
filters (encoder/decoder) by providing filter with has block IO as input
and stream of symbols as output. 

---
Vladimir

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


  reply	other threads:[~2004-05-08  7:29 UTC|newest]

Thread overview: 67+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-05-03  6:12 Vladimir N. Silyaev
2004-05-04 21:31 ` Benjamin Geer
2004-05-04 22:59   ` Yamagata Yoriyuki
2004-05-05  8:11     ` skaller
2004-05-05 15:48       ` Marcin 'Qrczak' Kowalczyk
2004-05-05 19:28         ` skaller
2004-05-05 17:33     ` Vladimir N. Silyaev
2004-05-05 17:31   ` Vladimir N. Silyaev
2004-05-07 22:11     ` Benjamin Geer
2004-05-08  7:29       ` Vladimir N. Silyaev [this message]
2004-05-09 17:35         ` Benjamin Geer
  -- strict thread matches above, loose matches on Subject: below --
2004-04-24  9:28 [Caml-list] [ANN] The Missing Library Nicolas Cannasse
2004-04-25  8:56 ` Common IO structure (was Re: [Caml-list] [ANN] The Missing Library) Yamagata Yoriyuki
2004-04-25 11:54   ` Gerd Stolpmann
2004-04-26 14:53     ` [Caml-list] Re: Common IO structure Yamagata Yoriyuki
2004-04-26 21:02       ` Gerd Stolpmann
2004-04-25 19:42   ` Common IO structure (was Re: [Caml-list] [ANN] The Missing Library) Nicolas Cannasse
2004-04-26 13:16     ` [Caml-list] Re: Common IO structure Yamagata Yoriyuki
2004-04-26 13:53       ` Jacques GARRIGUE
2004-04-26 14:26         ` Nicolas Cannasse
2004-04-28  6:52           ` Jacques GARRIGUE
2004-04-26 14:23       ` Nicolas Cannasse
2004-04-26 14:55         ` skaller
2004-04-26 15:26         ` Yamagata Yoriyuki
2004-04-26 19:28           ` Nicolas Cannasse
2004-04-26 20:56             ` Gerd Stolpmann
2004-04-26 21:14               ` John Goerzen
2004-04-26 22:32                 ` Gerd Stolpmann
2004-04-26 21:52               ` Benjamin Geer
2004-04-27 16:00               ` Yamagata Yoriyuki
2004-04-27 21:51                 ` Gerd Stolpmann
2004-04-27 19:08               ` Nicolas Cannasse
2004-04-27 22:22                 ` Gerd Stolpmann
2004-04-28  7:42                   ` Nicolas Cannasse
2004-04-29 10:13                 ` Yamagata Yoriyuki
2004-04-27 15:43             ` Yamagata Yoriyuki
2004-04-27 16:17               ` Nicolas Cannasse
2004-04-27 16:58                 ` Yamagata Yoriyuki
2004-04-27 23:35                   ` Benjamin Geer
2004-04-28  3:44                     ` John Goerzen
2004-04-28 13:01                       ` Richard Jones
2004-04-28 21:30                       ` Benjamin Geer
2004-04-28 21:44                         ` John Goerzen
2004-04-28 22:41                           ` Richard Jones
2004-04-29 11:51                             ` Benjamin Geer
2004-04-29 12:03                               ` Richard Jones
2004-04-29 15:16                                 ` Benjamin Geer
2004-04-29 10:27                           ` Yamagata Yoriyuki
2004-04-29 13:03                             ` John Goerzen
2004-04-29 13:40                               ` Yamagata Yoriyuki
2004-04-29 14:02                                 ` John Goerzen
2004-04-29 15:31                                   ` Yamagata Yoriyuki
2004-04-29 17:31                                     ` james woodyatt
2004-04-29 23:53                                       ` Benjamin Geer
2004-04-30  4:10                                         ` james woodyatt
2004-04-29 11:23                           ` Benjamin Geer
2004-04-29 12:23                             ` Richard Jones
2004-04-29 15:10                               ` Benjamin Geer
2004-04-29 15:35                                 ` John Goerzen
2004-04-29 15:46                                   ` Benjamin Geer
2004-04-29 15:58                                     ` Richard Jones
2004-04-29 20:41                                     ` John Goerzen
2004-04-29 22:35                                       ` Benjamin Geer
2004-05-01 14:37                               ` Brian Hurt
2004-04-29 13:23                             ` John Goerzen
2004-04-29 14:12                               ` John Goerzen
2004-04-29 15:37                               ` Benjamin Geer
2004-04-28  7:05                     ` Nicolas Cannasse
2004-04-28  0:20                   ` skaller
2004-04-28  3:39                   ` John Goerzen
2004-04-28 13:04                   ` Richard Jones

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20040508072922.GA2771@server.vns.oc.ca.us \
    --to=vsilyaev@mindspring.com \
    --cc=ben@socialtools.net \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).