unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
From: mark@markwitmer.com
To: guile-user@gnu.org
Subject: Re: asynchronous socket library
Date: Tue, 16 Jul 2013 23:07:13 -0700	[thread overview]
Message-ID: <8761w9n2i6.fsf@mark-desktop.PK5001Z> (raw)
In-Reply-To: CA+XASoUxU4Yiz+mtyMhB6a6dBmRU9mqma0zfXLOXVPwfkv0bFQ@mail.gmail.com

Aleix Conchillo Flaqué <aconchillo@gmail.com> writes:

> Hi,
>
> I was wondering if there is (or someone is working on) an asynchronous
> socket library for Guile. I was thinking in a pure scheme library (not
> bindings for libevent or some other).
>
> Thanks,
>
> Aleix
>
>

I spent some time working on nonblocking input from a socket for my X
bindings. You can do it in pure Scheme if you're willing to live without
epoll(): Guile includes bindings for both select() and poll() (the
latter is in the undocumented (ice-9 poll) module). I used select()
because it had a section in the manual; I figure it's more "official"
and the docs make it easier for other people to follow the code.

I'm not sure how generally applicable all of my code is since it's
listening specifically for X events and replies, but the way I wait on
the socket looks like this. You have to handle interrupts manually:

(define (file-ready? fd)
    (define (do-select)
      (select (list fd) '() '()   )) 
 ;; ----------------------------^ [SECS] [USECS]
 ;; You can include an optional timeout in seconds and one in microseconds
    (define (on-error . args)
       (if (= (system-error-errno args) EINTR)
         '(() () ()) ;; This is what select returns when the file's unavailable
         (apply throw args)))
    (memq fd (car (catch 'system-error do-select on-error))))

(if (file-ready? fd)
    ... do the file operation ...
    ... loop or do something else instead ...)

Reading and writing to a socket seems to lend itself well to custom
binary ports, but then I think you're stuck with an opaque buffer -- you
can't properly ask the binary port if the next read beyond one byte will
block or not, since it might have stuff buffered or it might not. I'd
love to be wrong about that if someone happens to know how to check for
the amount remaining in a custom binary port's buffer.

Because of that, my code directly uses recv! every time it wants to read
from the socket, event if it just needs one byte. I don't think that
approach makes for very elegant nonblocking i/o, but it's been
performing well enough.

You can take a look at this for some more ideas (hopefully good ones):

https://github.com/mwitmer/guile-xcb/blob/prompts/xcb/xml/connection.scm

-- 
Mark Witmer




  parent reply	other threads:[~2013-07-17  6:07 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 [this message]
2013-07-17  7:13   ` Mark H Weaver
2013-07-17 16:49     ` mark
2013-08-24 21:33       ` Mark H Weaver
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=8761w9n2i6.fsf@mark-desktop.PK5001Z \
    --to=mark@markwitmer.com \
    --cc=guile-user@gnu.org \
    /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).