From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: =?utf-8?Q?Ludovic_Court=C3=A8s?= Newsgroups: gmane.lisp.guile.devel Subject: Re: [PATCH] Make get-bytevector-all suspendable. Date: Sat, 01 Jun 2024 11:11:06 +0200 Message-ID: <87bk4lqb85.fsf@gnu.org> References: <20230720140103.23221-1-mail@cbaines.net> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="3455"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Cc: guile-devel@gnu.org To: Christopher Baines Original-X-From: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org Sat Jun 01 11:11:39 2024 Return-path: Envelope-to: guile-devel@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 1sDKm2-0000iA-KI for guile-devel@m.gmane-mx.org; Sat, 01 Jun 2024 11:11:38 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sDKlg-0005vP-8W; Sat, 01 Jun 2024 05:11:16 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sDKlb-0005ul-0f for guile-devel@gnu.org; Sat, 01 Jun 2024 05:11:12 -0400 Original-Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sDKlY-0002WV-VR; Sat, 01 Jun 2024 05:11:10 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-Version:In-Reply-To:Date:References:Subject:To: From; bh=eXy94x+s1KX5du3OvOmKXkjmTu2w0Uhr/4qolxLfQEg=; b=hMDe7ZOlDSye0KfjKTbv 6RSJFCm828UOBnIpsWnQf+mGqyAQ0pl9l4onsez4oFH2sZfcYP0OTPxhGkb1H49t6T38mx0N7XYMH 9YH3m8lpHVXbNkMUqaJJfa79SGLaK09/sSqj7c5ZqHQ+YgYi/T7uo42LL2fMa1wl13CFKlQVWKpxC 4y4PMLDHXmbc67K394tFeG9lLOKDiarL9gq1aTShDnqZyANHmKPxKve0dKDvIDETsEGPeVKqo+qcE xC0kyRgsQFb0+r/qz6Mgv2WWPl88I5caS9OhCKvG2nmRQcc+W1+cenML6VOkQVgV8wT5fT4rKWVe0 V4iHuZpw4rWbfg==; X-URL: http://www.fdn.fr/~lcourtes/ X-Revolutionary-Date: Quartidi 14 Prairial an 232 de la =?utf-8?Q?R=C3=A9v?= =?utf-8?Q?olution=2C?= jour de l'Acacia X-PGP-Key-ID: 0x090B11993D9AEBB5 X-PGP-Key: http://www.fdn.fr/~lcourtes/ludovic.asc X-PGP-Fingerprint: 3CE4 6455 8A84 FDC6 9DB4 0CFB 090B 1199 3D9A EBB5 X-OS: x86_64-pc-linux-gnu In-Reply-To: <20230720140103.23221-1-mail@cbaines.net> (Christopher Baines's message of "Thu, 20 Jul 2023 15:01:03 +0100") X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.29 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-mx.org@gnu.org Original-Sender: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.lisp.guile.devel:22424 Archived-At: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi Chris, Christopher Baines skribis: > I'm looking at this since it's used in (web response) > read-response-body. > > * module/ice-9/suspendable-ports.scm (get-bytevector-all): New > procedure. > (port-bindings): Add it. Given that =E2=80=98get-bytevector-n!=E2=80=99 already has a variant in suspendable-ports.scm, my preference would be to rewrite =E2=80=98get-bytevector-all=E2=80=99 in Scheme (patch attached). That way,= it would naturally be suspendable. (It=E2=80=99s also in line with the general stra= tegy of moving things to Scheme.) I don=E2=80=99t expect significant performance difference compared to the C implementation since that is dominated by allocations and I/O. Thoughts? Ludo=E2=80=99. --=-=-= Content-Type: text/x-patch Content-Disposition: inline diff --git a/libguile/r6rs-ports.c b/libguile/r6rs-ports.c index 7c51bf617..ffa1e1b2b 100644 --- a/libguile/r6rs-ports.c +++ b/libguile/r6rs-ports.c @@ -1,4 +1,4 @@ -/* Copyright 2009-2011,2013-2015,2018-2019,2023 +/* Copyright 2009-2011,2013-2015,2018-2019,2023,2024 Free Software Foundation, Inc. This file is part of Guile. @@ -393,58 +393,23 @@ SCM_DEFINE (scm_get_bytevector_some_x, "get-bytevector-some!", 4, 0, 0, } #undef FUNC_NAME -SCM_DEFINE (scm_get_bytevector_all, "get-bytevector-all", 1, 0, 0, - (SCM port), - "Read from @var{port}, blocking as necessary, until " - "the end-of-file is reached. Return either " - "a new bytevector containing the data read or the " - "end-of-file object (if no data were available).") -#define FUNC_NAME s_scm_get_bytevector_all -{ - SCM result; - size_t c_len, c_count; - size_t c_read, c_total; - - SCM_VALIDATE_BINARY_INPUT_PORT (1, port); +static SCM get_bytevector_all_var; - c_len = c_count = 4096; - result = scm_c_make_bytevector (c_count); - c_total = c_read = 0; - - do - { - if (c_read > c_len - c_total) - { - /* Grow the bytevector. */ - SCM prev = result; - - if (INT_ADD_OVERFLOW (c_len, c_len)) - scm_num_overflow (FUNC_NAME); - - result = scm_c_make_bytevector (c_len * 2); - memcpy (SCM_BYTEVECTOR_CONTENTS (result), - SCM_BYTEVECTOR_CONTENTS (prev), - c_total); - c_count = c_len; - c_len *= 2; - } - - /* `scm_c_read ()' blocks until C_COUNT bytes are available or EOF is - reached. */ - c_read = scm_c_read_bytes (port, result, c_total, c_count); - c_total += c_read, c_count -= c_read; - } - while (c_count == 0); - - if (c_total == 0) - return SCM_EOF_VAL; +static void +init_bytevector_io_vars (void) +{ + get_bytevector_all_var = + scm_c_public_lookup ("ice-9 binary-port", "get-bytevector-all"); +} - if (c_len > c_total) - return scm_c_shrink_bytevector (result, c_total); +SCM +scm_get_bytevector_all (SCM port) +{ + static scm_i_pthread_once_t once = SCM_I_PTHREAD_ONCE_INIT; + scm_i_pthread_once (&once, init_bytevector_io_vars); - return result; + return scm_call_1 (scm_variable_ref (get_bytevector_all_var), port); } -#undef FUNC_NAME diff --git a/module/ice-9/binary-ports.scm b/module/ice-9/binary-ports.scm index b7eddc93d..864d9ef9a 100644 --- a/module/ice-9/binary-ports.scm +++ b/module/ice-9/binary-ports.scm @@ -1,5 +1,5 @@ ;;; binary-ports.scm --- Binary IO on ports -;;; Copyright (C) 2009-2011,2013,2016,2019,2021,2023 Free Software Foundation, Inc. +;;; Copyright (C) 2009-2011,2013,2016,2019,2021,2023,2024 Free Software Foundation, Inc. ;;; ;;; This library is free software: you can redistribute it and/or modify ;;; it under the terms of the GNU Lesser General Public License as @@ -27,6 +27,7 @@ (define-module (ice-9 binary-ports) #:use-module (rnrs bytevectors) + #:autoload (rnrs bytevectors gnu) (bytevector-slice) #:use-module (ice-9 match) #:use-module (ice-9 custom-ports) #:export (eof-object @@ -180,3 +181,29 @@ bytevector composed of the bytes written into the port is returned." ;; FIXME: Instead default to current encoding, if ;; someone reads text from this port. #:encoding 'ISO-8859-1 #:conversion-strategy 'error)) + + +;;; +;;; Binary input. +;;; + +(define (get-bytevector-all port) + "Read from @var{port}, blocking as necessary, until +the end-of-file is reached. Return either a new bytevector containing +the data read or the end-of-file object (if no data were available)." + (define initial-capacity 4096) + + (let loop ((bv (make-bytevector initial-capacity)) + (capacity initial-capacity) + (size 0)) + (match (get-bytevector-n! port bv size (- capacity size)) + ((? eof-object?) + (bytevector-slice bv 0 size)) + (read + (let ((size (+ read size))) + (if (= capacity size) + (let* ((capacity (* capacity 2)) + (new (make-bytevector capacity))) + (bytevector-copy! bv 0 new 0 size) + (loop new capacity size)) + (loop bv capacity size))))))) --=-=-=--