unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
From: Mark H Weaver <mhw@netris.org>
To: mark@markwitmer.com
Cc: guile-user@gnu.org
Subject: Re: asynchronous socket library
Date: Sat, 24 Aug 2013 17:33:05 -0400	[thread overview]
Message-ID: <87d2p2bwq6.fsf@tines.lan> (raw)
In-Reply-To: <87a9ll9loc.fsf@markwitmer.com> (mark@markwitmer.com's message of "Wed, 17 Jul 2013 09:49:07 -0700")

Hi Mark,

Sorry for taking so long to respond.

mark@markwitmer.com writes:

> Mark H Weaver <mhw@netris.org> writes:
>
>> mark@markwitmer.com writes:
>>> Reading and writing to a socket seems to lend itself well to custom
>>> binary ports,
>>
>> Why do you say that?  For most purposes, Guile's native file ports are
>> superior, and they seem the natural choice for sockets.
>>
>
> I over-generalized. In my application, I'm using the X protocol, which
> is a binary one. I've been so involved with that I forgot that much of
> the time you want to read/write character data from a socket.

Guile's native file ports (which also work on sockets) can be used for
binary data as well as character data.  There's no need to create a
custom binary port for this purpose.  Indeed, the custom ports have
several major disadvantages compared to the native file ports.

>> 'get-bytevector-some' from (rnrs io ports) might do what you need.  If
>> there's at least one byte available it will not block, but in practice
>> it reads much more than that (for buffered ports).  Guile 2.0.9 has a
>> nice fast implementation.  Prior to 2.0.9, it was less so.
>>
>> In more detail: as of 2.0.9, 'get-bytevector-some' will simply copy the
>> input buffer managed by Guile into a bytevector and return it.  If
>> Guile's input buffer is empty, it will try to refill the buffer using
>> the port type's 'fill_input' method.  For file ports this is
>> fports.c:fport_fill_input, and for custom binary ports it's
>> r6rs-ports.c:cbip_fill_input.
>
> In order to know if the port has at least one byte ready, you need to be
> able to call 'char-ready?', don't you? And as you mentioned, that
> doesn't work on custom binary ports. I'm still exploring this part of
> Guile so I might not have the details right.
>
>>
>> So again I ask, why use custom binary ports for sockets?
>>
>
> Thanks for the detailed explanation; I think I'll move away from
> them. Were they added just to meet the r6rs spec? Are there any good
> uses for custom binary ports that you're aware of?

Yes, custom ports are needed if the data that's being read is not coming
from a file, pipe, device, socket, string, or bytevector (the cases
covered by Guile's existing native port types; maybe I'm forgetting
some).  Similarly for writing.

For example, suppose you wanted a make an input port that reads
keypresses from a GUI interface.  In this case, the keypresses are
received via events during the main event loop.  There is no underlying
POSIX file descriptor to read from, nor is there a single Scheme string
or bytevector.  You could use pipes I suppose, but that assumes POSIX.
Another way is to make a custom port.

In the case of guile-xcb, I see two places where custom ports are used
in auth.scm.  Here's the first case:

--8<---------------cut here---------------start------------->8---
    (define auth-file (open-file (getenv "XAUTHORITY") "rb"))

    (define port
      (make-custom-binary-input-port
       "xcb-auth-input"
       (lambda (bv start count)
         (do ((n 0 (1+ n))
              (ch (read-char auth-file) (read-char auth-file)))
             ((or (>= n count) (eof-object? ch)) n)
           (bytevector-u8-set!
            bv (+ start n) (char->integer ch))))
       #f #f (lambda () (close-port port))))
--8<---------------cut here---------------end--------------->8---

First of all, that '(close-port port)' is wrong.  Here you are trying to
tell Guile how to close 'port', and this just recurses.  I guess it
should be (close-port auth-file)'.

However, I don't see why this custom port is needed at all.  You've
already opened 'auth-file' in binary mode, so you should be able to use
it directly, i.e. replace the above code with:

    (define port (open-file (getenv "XAUTHORITY") "rb"))

The other case is here (also in auth.scm):

--8<---------------cut here---------------start------------->8---
    (define (read! bv start count)
      (let* ((in-bv (make-bytevector count))
             (bytes-read (recv! sock in-bv)))
        (bytevector-copy! in-bv 0 bv start bytes-read)
        bytes-read))
    (define port (make-custom-binary-input-port "xcb-input" read! #f #f #f))
--8<---------------cut here---------------end--------------->8---

Again, I don't see why this custom port should be needed.
You should be able to use 'sock' directly.

Anyway, thanks for working on this! :)

     Regards,
       Mark



  reply	other threads:[~2013-08-24 21:33 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-15 23:41 asynchronous socket library Aleix Conchillo Flaqué
2013-07-16  1:03 ` Nala Ginrut
2013-07-16  1:42   ` Aleix Conchillo Flaqué
2013-07-16  6:15 ` Javier Sancho
2013-07-16  7:02   ` Aleix Conchillo Flaqué
2013-07-16  7:03     ` Aleix Conchillo Flaqué
2013-07-16  7:36     ` Chaos Eternal
2013-07-16 15:24       ` Aleix Conchillo Flaqué
2013-07-16 15:58         ` Chaos Eternal
2013-07-16 17:02           ` Aleix Conchillo Flaqué
2013-07-16  7:50     ` Thien-Thi Nguyen
2013-07-16 15:26       ` Aleix Conchillo Flaqué
2013-07-17  6:07 ` mark
2013-07-17  7:13   ` Mark H Weaver
2013-07-17 16:49     ` mark
2013-08-24 21:33       ` Mark H Weaver [this message]
2013-08-25 22:26         ` mark.d.witmer

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

  List information: https://www.gnu.org/software/guile/

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

  git send-email \
    --in-reply-to=87d2p2bwq6.fsf@tines.lan \
    --to=mhw@netris.org \
    --cc=guile-user@gnu.org \
    --cc=mark@markwitmer.com \
    /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 read-only IMAP folder(s) and NNTP newsgroup(s).