all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: "Ludovic Courtès" <ludo@gnu.org>
To: 63516@debbugs.gnu.org
Cc: "Ludovic Courtès" <ludo@gnu.org>
Subject: bug#63516: [PATCH Guile-Netlink 04/11] connection: Add support for suspendable sockets.
Date: Tue, 23 May 2023 14:39:44 +0200	[thread overview]
Message-ID: <20230523123951.6225-5-ludo@gnu.org> (raw)
In-Reply-To: <20230523123951.6225-1-ludo@gnu.org>

* netlink/connection.scm (syscall->procedure): Add #:waiter.
Distinguish first argument and call WAITER upon EWOULDBLOCK or EAGAIN
when the first argument is a port.
(ffi-sendto, ffi-recvmsg, ffi-bind): Pass #:waiter.
(connect, send-msg, receive-msg): Pass SOCK instead of (fileno sock).
---
 netlink/connection.scm | 45 ++++++++++++++++++++++++++++--------------
 1 file changed, 30 insertions(+), 15 deletions(-)

diff --git a/netlink/connection.scm b/netlink/connection.scm
index f4a5cc6..42f7dbb 100644
--- a/netlink/connection.scm
+++ b/netlink/connection.scm
@@ -26,6 +26,8 @@
   #:use-module (srfi srfi-34)
   #:use-module (srfi srfi-35)
   #:use-module (srfi srfi-71)
+  #:autoload   (ice-9 suspendable-ports) (current-read-waiter
+                                          current-write-waiter)
   #:export (connect
             connect-route
             close-socket
@@ -36,27 +38,40 @@
 
 (define libc (dynamic-link))
 
-(define (syscall->procedure return-type function
-                            argument-types)
+(define* (syscall->procedure return-type function
+                             argument-types
+                             #:key waiter)
   "Return a procedure that calls FUNCTION, a syscall wrapper from the C library
-with the given RETURN-TYPE and ARGUMENT-TYPES."
+with the given RETURN-TYPE and ARGUMENT-TYPES.  When WAITER is true and the
+first argument is a port, call it upon EAGAIN or EWOULDBLOCK."
   (let ((proc (pointer->procedure return-type
                                   (dynamic-func function libc)
                                   argument-types
                                   #:return-errno? #t)))
-    (lambda args
-      (let ((ret errno (apply proc args)))
-        (when (< ret 0)
-          (throw 'system-error function "~A"
-                 (list (strerror errno)) (list errno)))
-        ret))))
+    (lambda (first . rest)
+      (let loop ()
+        (let ((ret errno (apply proc
+                                (if (port? first) (fileno first) first)
+                                rest)))
+          (if (< ret 0)
+              (if (and (memv errno (list EAGAIN EWOULDBLOCK))
+                       (port? first) waiter)
+                  (begin
+                    ((waiter) first)
+                    (loop))
+                  (throw 'system-error function "~A"
+                         (list (strerror errno)) (list errno)))
+              ret))))))
 
 (define ffi-sendto
-  (syscall->procedure int "sendto" (list int '* size_t int '* int)))
+  (syscall->procedure int "sendto" (list int '* size_t int '* int)
+                      #:waiter (lambda () (current-write-waiter))))
 (define ffi-recvmsg
-  (syscall->procedure int "recvmsg" (list int '* int)))
+  (syscall->procedure int "recvmsg" (list int '* int)
+                      #:waiter (lambda () (current-read-waiter))))
 (define ffi-bind
-  (syscall->procedure int "bind" (list int '* int)))
+  (syscall->procedure int "bind" (list int '* int)
+                      #:waiter (lambda () (current-read-waiter))))
 
 ;; define simple functions to open/close sockets
 (define (open-socket proto)
@@ -89,7 +104,7 @@ such as 'bind' cannot handle."
 
 (define* (connect proto addr)
   (let ((sock (open-socket proto)))
-    (ffi-bind (fileno sock)
+    (ffi-bind sock
               (bytevector->pointer addr)
               12)
     sock))
@@ -105,7 +120,7 @@ such as 'bind' cannot handle."
   (let* ((len (data-size msg))
          (bv (make-bytevector len)))
     (serialize msg 0 bv)
-    (ffi-sendto (fileno sock) (bytevector->pointer bv) len 0 %null-pointer 0)))
+    (ffi-sendto sock (bytevector->pointer bv) len 0 %null-pointer 0)))
 
 (define* (receive-msg sock #:key (addr (get-addr AF_NETLINK 0 0)))
   (let* ((len (* 1024 32))
@@ -115,7 +130,7 @@ such as 'bind' cannot handle."
                              iovec 1
                              %null-pointer 0
                              0))
-         (size (ffi-recvmsg (fileno sock) msghdr 0))
+         (size (ffi-recvmsg sock msghdr 0))
          (answer (make-bytevector size)))
     (when (> size (* 1024 32))
       (raise (condition (&netlink-answer-too-big-error (size size)))))
-- 
2.40.1





  parent reply	other threads:[~2023-05-23 12:42 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-15  9:30 bug#63516: Static networking should wait for interfaces to be up Ludovic Courtès
2023-05-20 23:03 ` Ludovic Courtès
2023-05-23 12:39   ` bug#63516: [PATCH Guile-Netlink 00/11] Add 'wait-for-link' and related code Ludovic Courtès
2023-05-23 12:39     ` bug#63516: [PATCH Guile-Netlink 01/11] connection: Remove unused procedure Ludovic Courtès
2023-05-23 12:39     ` bug#63516: [PATCH Guile-Netlink 02/11] connection: Use Guile's 'socket' procedure to open a socket Ludovic Courtès
2023-05-23 12:39     ` bug#63516: [PATCH Guile-Netlink 03/11] connection: Throw upon errors in FFI bindings Ludovic Courtès
2023-05-23 12:39     ` Ludovic Courtès [this message]
2023-05-23 12:39     ` bug#63516: [PATCH Guile-Netlink 05/11] connection: Allow users to pass extra SOCK_ flags to 'socket' Ludovic Courtès
2023-05-23 12:39     ` bug#63516: [PATCH Guile-Netlink 06/11] link: Extract 'new-link-message->link' Ludovic Courtès
2023-05-23 12:39     ` bug#63516: [PATCH Guile-Netlink 07/11] addr: Extract 'new-address-message->address' Ludovic Courtès
2023-05-23 12:39     ` bug#63516: [PATCH Guile-Netlink 08/11] connection: Add 'add-socket-membership' Ludovic Courtès
2023-05-23 12:39     ` bug#63516: [PATCH Guile-Netlink 09/11] error: Add 'sub-type' field to '&netlink-decoder-error' and use it Ludovic Courtès
2023-05-23 12:39     ` bug#63516: [PATCH Guile-Netlink 10/11] doc: Add indexes Ludovic Courtès
2023-05-23 12:39     ` bug#63516: [PATCH Guile-Netlink 11/11] link: Add 'wait-for-link' Ludovic Courtès
2023-05-23 18:53     ` bug#63516: [PATCH Guile-Netlink 00/11] Add 'wait-for-link' and related code Julien Lepiller
2023-05-24 14:55       ` Ludovic Courtès
2023-05-24 15:12         ` Julien Lepiller
2023-06-14 21:53   ` bug#63516: Static networking should wait for interfaces to be up Ludovic Courtès

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

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230523123951.6225-5-ludo@gnu.org \
    --to=ludo@gnu.org \
    --cc=63516@debbugs.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.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/guix.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.