guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: asynchronous socket library


From: mark
Subject: Re: asynchronous socket library
Date: Tue, 16 Jul 2013 23:07:13 -0700
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux)

Aleix Conchillo Flaqué <address@hidden> 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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]