From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Andreas Rottmann Newsgroups: gmane.lisp.guile.bugs Subject: bug#39610: R6RS `flush-output-port` not playing along with `transcoded-port` Date: Sun, 29 Mar 2020 23:15:49 +0200 Message-ID: <87bloe981m.fsf@r0tty.org> References: <87d0agu2yd.fsf@londo.h.r0tty.org> <87wo8orvr9.fsf@londo.h.r0tty.org> <874kuhzj6l.fsf@gnu.org> <87r1xkj96g.fsf@r0tty.org> <874kufs9xa.fsf@gnu.org> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="127211"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: mu4e 1.3.6; emacs 27.0.50 Cc: 39610@debbugs.gnu.org To: Ludovic =?UTF-8?Q?Court=C3=A8s?= Original-X-From: bug-guile-bounces+guile-bugs=m.gmane-mx.org@gnu.org Sun Mar 29 23:17:12 2020 Return-path: Envelope-to: guile-bugs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jIfIu-000WzA-LE for guile-bugs@m.gmane-mx.org; Sun, 29 Mar 2020 23:17:12 +0200 Original-Received: from localhost ([::1]:41772 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jIfIt-0005Sr-Ed for guile-bugs@m.gmane-mx.org; Sun, 29 Mar 2020 17:17:11 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:49878) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jIfIn-0005SY-QS for bug-guile@gnu.org; Sun, 29 Mar 2020 17:17:07 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jIfIm-000834-7j for bug-guile@gnu.org; Sun, 29 Mar 2020 17:17:05 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:48474) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1jIfIk-00081Y-LM for bug-guile@gnu.org; Sun, 29 Mar 2020 17:17:03 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1jIfIk-0004Py-Fy for bug-guile@gnu.org; Sun, 29 Mar 2020 17:17:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Andreas Rottmann Original-Sender: "Debbugs-submit" Resent-CC: bug-guile@gnu.org Resent-Date: Sun, 29 Mar 2020 21:17:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 39610 X-GNU-PR-Package: guile Original-Received: via spool by 39610-submit@debbugs.gnu.org id=B39610.158551656216890 (code B ref 39610); Sun, 29 Mar 2020 21:17:02 +0000 Original-Received: (at 39610) by debbugs.gnu.org; 29 Mar 2020 21:16:02 +0000 Original-Received: from localhost ([127.0.0.1]:60020 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jIfHl-0004O2-NZ for submit@debbugs.gnu.org; Sun, 29 Mar 2020 17:16:02 -0400 Original-Received: from ghost.xx.vu ([185.33.11.101]:45941) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jIfHi-0004Np-If for 39610@debbugs.gnu.org; Sun, 29 Mar 2020 17:15:59 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=r0tty.org; s=20200309; t=1585516550; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UxCZA/EBuhKtr2JDdrUa8F7baS6U3TqfpAsVB6IoEBA=; b=t/c/CF1c1q43heJAysvzWeWhmZNDhl6dy1lOY8El+U2zcuDMEZmdkAyisvyVUb/zIf+m/1 Yi01EFMjTSmKsDRsMTCJPt5WHuqWZwNI/5V2DJDbsRSLW2O6+7KmNCXlHLFDI/QdKI6vx/ U/E6adUXaZlNr0B5nG5LAf4d5cmO4Mo= Original-Received: from mail0.xx.vu (localhost [::1]) by ghost.xx.vu (OpenSMTPD) with ESMTP id 56a1445f; Sun, 29 Mar 2020 21:15:50 +0000 (UTC) Original-Received: from londo ([213.162.73.46]) by mail0.xx.vu with ESMTPSA id o3J3GQYQgV55cAEAg/rtjg (envelope-from ); Sun, 29 Mar 2020 21:15:50 +0000 In-reply-to: <874kufs9xa.fsf@gnu.org> X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.51.188.43 X-BeenThere: bug-guile@gnu.org List-Id: "Bug reports for GUILE, GNU's Ubiquitous Extension Language" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-guile-bounces+guile-bugs=m.gmane-mx.org@gnu.org Original-Sender: "bug-guile" Xref: news.gmane.io gmane.lisp.guile.bugs:9703 Archived-At: Ludovic Court=C3=A8s writes: > Hi, > > Andreas Rottmann skribis: > >>> Andreas Rottmann skribis: >>> >>>> Andreas Rottmann writes: >>>> >>>>> [...] I isolated the cause; the following snippet hangs on Guile 2.2 >>>>> and 3.0, while it worked as expected on 2.0: >>>>> >>>>> [...] >>>>> >>>>> It seems the underlying port is no longer flushed to the OS, so the >>>>> `get-u8` now hangs waiting for input, starting with Guile 2.2. >>>>> >>>> [...] >>> >>> Actually I think the code above behaves as expected. =E2=80=98pipe=E2= =80=99 returns >>> buffered ports by default. When flushing the transcoded port, >>> =E2=80=98transcoded_port_write=E2=80=99 is called, but then bytes writt= en to the pipe >>> are buffered. >>> >>> The fix is to add: >>> >>> (setvbuf (cdr p) 'none) >>> >>> Does that make sense? >>> >> It makes sense, and I can confirm that it makes the boiled-down example >> I posted work. >> >> However, I'm not sure it is the expected behavior. Regardless of >> buffering modes used, I would expect a `flush-output-port` in a "port >> stack" (as produced by `transcoded-output-port`) to propagate all the >> way to the OS. It seems that was the case in Guile 2.0, as I'm pretty >> sure I observed the "breaking" behavior change with 8399e7af5 applied, >> and not with the commit preceding it. > > Port types don=E2=80=99t have a =E2=80=9Cflush=E2=80=9D operation, only = =E2=80=9Cwrite=E2=80=9D. Thus, it=E2=80=99s > impossible to define a port type that would propagate flushes. > There are pros and cons I guess, but it seems like a reasonable choice > to me. > > When implementing a =E2=80=9Cproxying=E2=80=9D port type like =E2=80=98tr= anscoded-port=E2=80=99 that > does its own buffering, it=E2=80=99s probably OK to say that it=E2=80=99s= the proxy=E2=80=99s > responsibility to ensure there=E2=80=99s no double-buffering taking place. > In my understanding, the "proxy type" is the R6RS transcoded port in this case, which has no control over the underlying port, but provides a flush operation (`flush-output-port`), which R6RS specifies as: Flushes any buffered output from the buffer of output-port to the underlying file, device, or object. The flush-output-port procedure returns unspecified values. So if I obtain a transcoded port from a pipe port, and call `flush-output-port` on the transcoded port, I'd expect the bytes to end up at _least_ at the pipe port. That probably happens currently; however, the thing is that R6RS also says about `transcoded-port`: As a side effect, however, transcoded-port closes binary-port in a special way that allows the new textual port to continue to use the byte source or sink represented by binary-port, even though binary-port itself is closed and cannot be used by the input and output operations described in this chapter. So, I conclude: when you use `transcoded-port` with any underlying Guile port, and you care about buffering behavior, you _need_ to set the underlying port's buffer mode to 'none`, _before_ constructing the transcoded port. I have not tried if Guile enforces the "specially closed mode", but I am thinking in the context of an abstraction over `pipe` and `primitive-fork`, intended to provide a basis for "pure" R6RS code [1], so the client code cannot just call Guile's `setvbuf`, without losing portability. [1] https://github.com/rotty/spells/blob/master/spells/process/compat.guile= .sls Do you agree with that conclusion? [ After writing the above, I realize that might be what you meant, after all: do you propose that, as a fix, `transcoded-port` sets the buffer mode of the underlying port to `none`? ] I must admit that I am confused -- how can a port type have no flush operation (which is evidently true from looking at scm_t_port_type), and Guile's `force-output` procedure, generic over port types, still exist? >> If the current behavior is indeed the intended one, we should make sure >> the docs somehow reflect this caveat, as I imagine it may surprise >> future Guile users which happen to use its R6RS support and pipes in >> combination. > > Maybe we should not document this specific combination but rather the > more general issue? I=E2=80=99m not sure how to do that. Thoughts? > I now realized I need to wrap my head around the changed port implementation, and how it relates to R6RS in general, and `transcoded-port` specifically, before starting to think about documentation. I think I have identified another related issue, this time for reading from `trancoded-port`, but I'd rather make sure we have a shared understanding of the expected flushing and buffering behavior, before bringing that up. Regards, Rotty