From: Andy Wingo <wingo@pobox.com>
To: Chris Vine <chris@cvine.freeserve.co.uk>
Cc: "Ludovic Courtès" <ludo@gnu.org>, guile-user <guile-user@gnu.org>,
guile-devel <guile-devel@gnu.org>
Subject: Re: anyone define port types?
Date: Sun, 19 Jun 2016 11:13:17 +0200 [thread overview]
Message-ID: <8760t5mthu.fsf@pobox.com> (raw)
In-Reply-To: <20160612092513.3eb1c8a3@laptop.homenet> (Chris Vine's message of "Sun, 12 Jun 2016 09:25:13 +0100")
Hi :)
On Sun 12 Jun 2016 10:25, Chris Vine <chris@cvine.freeserve.co.uk> writes:
>> http://www.gnu.org/software/guile/docs/master/guile.html/Input-and-Output.html
>
> The documentation indicates that with the C ports implementation in
> guile-2.2, reads will block on non-blocking file descriptors.
Correct.
> This will stop the approach to asynchronicity used in 8sync and
> guile-a-sync (the latter of which I have written) from working
> correctly with sockets on linux operating systems, because at present
> both of these use guile's wrapper for select.
The trouble is that AFAIU there is no way to make non-blocking input
work reliably with O_NONBLOCK file descriptors in the approach that
Guile has always used.
As you know, the current behavior for Guile 2.0 is to throw an exception
when you get EAGAIN / EWOULDBLOCK. If I am understanding you correctly,
your approach is to only read from a port if you have done a select() /
poll() / etc on it beforehand indicating that you can read at least one
byte.
The problem with this is not only spurious wakeups, as you note, but
also buffering. Throwing an exception when reading in Guile 2.0 will
discard input buffers in many cases. Likewise when writing, you won't
be able to know how much you've written.
This goes not only for the explicit bufffers attached to ports and which
you can control with `setvbuf', but also implicit buffers, and it's in
this case that it's particularly pernicious: if you `read-char' on a
UTF-8 port, you might end up using local variables in the stack as a
buffer for reconstructing that codepoint. If you throw an exception in
the middle, you discard those bytes. Likewise for writing.
For suspendable ports, you don't throw an exception: you just assume the
operation is going to work, but if you get EAGAIN / EWOULDBLOCK, you
call the current-read-waiter / current-write-waiter and when that
returns retry the operation. Since it operates on the lowest level of
bytes, it's reliable. Looping handles the spurious wakeup case.
> However, to cater for other asynchronous implementations of file
> watches, would it be possible to provide a configurable option either
> to retain the guile-2.0 behaviour in such cases (which is to throw a
> system-error with errno set to EAGAIN or EWOULDBLOCK), or to provide a
> non-blocking alternative whereby the read operation would, instead of
> blocking, return some special value such as an EAGAIN symbol? Either
> would enable user code then to resume to its prompt and let other code
> execute.
Why not just (install-suspendable-ports!) and
(parameterize ((current-read-waiter my-read-waiter)) ...)
etc? It is entirely possible with Guile 2.1.3 to build an asynchronous
coroutine-style concurrent system in user-space using these primitives.
See the wip-ethread branch for an example implementation.
Andy
next prev parent reply other threads:[~2016-06-19 9:13 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-28 19:04 anyone define port types? Andy Wingo
2016-03-28 23:53 ` Matt Wette
2016-04-05 14:06 ` Mark H Weaver
2016-04-05 23:55 ` Matt Wette
2016-06-11 16:50 ` Andy Wingo
2016-03-29 7:58 ` tomas
2016-03-29 8:52 ` Nala Ginrut
2016-03-30 6:29 ` Panicz Maciej Godek
2016-03-30 11:18 ` Jan Nieuwenhuizen
2016-03-30 17:17 ` Panicz Maciej Godek
2016-03-30 17:53 ` Marko Rauhamaa
2016-03-30 19:02 ` Panicz Maciej Godek
2016-03-30 19:57 ` Marko Rauhamaa
2016-03-31 16:11 ` Barry Fishman
2016-03-31 19:28 ` Marko Rauhamaa
2016-03-30 19:43 ` Jan Wedekind
2016-03-30 20:07 ` Marko Rauhamaa
2016-03-30 21:01 ` Jan Wedekind
2016-03-30 22:44 ` Marko Rauhamaa
2016-03-31 20:42 ` Jan Wedekind
2016-03-31 22:28 ` Marko Rauhamaa
2016-06-11 16:53 ` Andy Wingo
2016-04-01 14:38 ` Ludovic Courtès
2016-06-11 16:57 ` Andy Wingo
2016-04-14 14:08 ` Ludovic Courtès
2016-06-11 17:02 ` Andy Wingo
2016-06-12 8:25 ` Chris Vine
2016-06-19 9:13 ` Andy Wingo [this message]
2016-06-19 9:55 ` Marko Rauhamaa
2016-06-19 15:27 ` Andy Wingo
2016-06-19 15:33 ` Chris Vine
2016-06-19 17:48 ` Andy Wingo
2016-06-19 20:09 ` Chris Vine
2016-06-20 3:38 ` William ML Leslie
2016-06-20 6:45 ` Chris Vine
2016-06-20 7:34 ` Andy Wingo
2016-06-20 9:01 ` Chris Vine
2016-06-22 22:44 ` Chris Vine
2016-06-23 7:36 ` Andy Wingo
2016-06-23 8:56 ` Andy Wingo
2016-06-23 9:24 ` Chris Vine
2016-06-23 9:50 ` Marko Rauhamaa
2016-06-23 10:43 ` Andy Wingo
2016-06-23 11:49 ` William ML Leslie
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=8760t5mthu.fsf@pobox.com \
--to=wingo@pobox.com \
--cc=chris@cvine.freeserve.co.uk \
--cc=guile-devel@gnu.org \
--cc=guile-user@gnu.org \
--cc=ludo@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).