From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Andy Wingo Newsgroups: gmane.lisp.guile.devel,gmane.lisp.guile.user Subject: Re: anyone define port types? Date: Sun, 19 Jun 2016 11:13:17 +0200 Message-ID: <8760t5mthu.fsf@pobox.com> References: <87y492mnjp.fsf@pobox.com> <87pots9tag.fsf@gnu.org> <87bn37wtf2.fsf@pobox.com> <20160612092513.3eb1c8a3@laptop.homenet> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1466327636 14751 80.91.229.3 (19 Jun 2016 09:13:56 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 19 Jun 2016 09:13:56 +0000 (UTC) Cc: Ludovic =?utf-8?Q?Court=C3=A8s?= , guile-user , guile-devel To: Chris Vine Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Sun Jun 19 11:13:42 2016 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1bEYnV-000873-27 for guile-devel@m.gmane.org; Sun, 19 Jun 2016 11:13:41 +0200 Original-Received: from localhost ([::1]:37992 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bEYnT-0005ef-Q0 for guile-devel@m.gmane.org; Sun, 19 Jun 2016 05:13:39 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:51458) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bEYnP-0005eW-56 for guile-devel@gnu.org; Sun, 19 Jun 2016 05:13:36 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bEYnK-0001RL-R8 for guile-devel@gnu.org; Sun, 19 Jun 2016 05:13:33 -0400 Original-Received: from pb-sasl2.pobox.com ([64.147.108.67]:56700 helo=sasl.smtp.pobox.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bEYnK-0001OO-LF; Sun, 19 Jun 2016 05:13:30 -0400 Original-Received: from sasl.smtp.pobox.com (unknown [127.0.0.1]) by pb-sasl2.pobox.com (Postfix) with ESMTP id E2DB61BC3A; Sun, 19 Jun 2016 05:13:25 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=pobox.com; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; s=sasl; bh=u1Fe7ZlVDXXM7J+yIoFUAzGz2dY=; b=mvWqPr SbW6vxQtUd71vKLtuIcTolI7RKMIZjQ/q3xeorvpINq65D99UQbGGItUEdYOfr71 lGZcWIh4jpiLGcEM0x5FSyz/ytPUSxL0XMpFplDNd16GSTRnKWjBvDkyKjQg6Zop LXisbgCZIx8jilxRV8Mt2ry+nbIeIkZJpes70= DomainKey-Signature: a=rsa-sha1; c=nofws; d=pobox.com; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; q=dns; s=sasl; b=lqSEpOYjRT+uYUsB92vEruvb0Jq3pFtQ mP18IOXYa6qEwmJh3hX8QDLU37dsmlSy/p3ht9E8+CSnSmBRCXJvH/YWT7v0/Yv8 wRp0GJ7GtqE/D8/8xDurbfZ7Bgg3YaEv7UhpEcDdr4rNvS/4MarSYRXDdPeIxwQQ Mpb/KR47zu4= Original-Received: from pb-sasl2.nyi.icgroup.com (unknown [127.0.0.1]) by pb-sasl2.pobox.com (Postfix) with ESMTP id C98621BC38; Sun, 19 Jun 2016 05:13:25 -0400 (EDT) Original-Received: from clucks (unknown [88.160.190.192]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by pb-sasl2.pobox.com (Postfix) with ESMTPSA id DAEFC1BC37; Sun, 19 Jun 2016 05:13:24 -0400 (EDT) In-Reply-To: <20160612092513.3eb1c8a3@laptop.homenet> (Chris Vine's message of "Sun, 12 Jun 2016 09:25:13 +0100") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) X-Pobox-Relay-ID: 13CC1CCE-35FE-11E6-9E61-28A6F1301B6D-02397024!pb-sasl2.pobox.com X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 64.147.108.67 X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Original-Sender: "guile-devel" Xref: news.gmane.org gmane.lisp.guile.devel:18345 gmane.lisp.guile.user:12646 Archived-At: Hi :) On Sun 12 Jun 2016 10:25, Chris Vine 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