unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* Concurrently write (out) and read (in) from ports
@ 2023-04-11 21:13 Zelphir Kaltstahl
  0 siblings, 0 replies; only message in thread
From: Zelphir Kaltstahl @ 2023-04-11 21:13 UTC (permalink / raw)
  To: Guile User

Hi Guile users!

I am currently trying to concurrently write to an output port and read from the 
corresponding input port, but something I am doing wrong and it does not work as 
I expected it to.

Here is what I have tried so far:

~~~~
(import
  ;; ports
  (ice-9 popen)
  (ice-9 textual-ports)
  (ice-9 binary-ports)

  (ice-9 exceptions)
  (ice-9 match)
  (ice-9 threads)
  (ice-9 futures)
  ;; let-values form
  (srfi srfi-11))


;; Define a pair of corresponding in and out ports.
(define-values (in out)
   (match-let ([(in . out) (pipe)])
     ;; make out line buffered
     ;; (setvbuf out 'line)
     (values in out)))


;; Just a helper function.
(define seconds
   (λ (s)
     (* s (expt 10 6))))


(define line-reader
   (λ ()
     "Read from an IN-PORT and write to OUT-PORT."
     (let ([in-port (current-input-port)]
           [out-port (current-output-port)])
       (let loop ([line (get-line in-port)])
         (simple-format #t "reader: reading from in-port\n")
         (unless (eof-object? line)
           (put-string out-port line)
           (loop (get-line in-port)))))))


;; Start writing endlessly.
(define writer-future
   (future
    (with-output-to-port out
      (λ () (endless-writer)))))


(with-output-to-port (current-output-port)
   (λ ()
     (with-input-from-port in
       (line-reader))))
~~~~

However, this does not work:

~~~~
guile -L . example.scm
~~~~

Does not display anything.

I also tried with explicitly passed ports:

~~~~
(import
  ;; ports
  (ice-9 popen)
  (ice-9 textual-ports)
  (ice-9 binary-ports)
  (ice-9 exceptions)
  ;; receive form
  ;; (ice-9 receive)
  ;; pattern matching
  (ice-9 match)
  ;; concurrency
  (ice-9 threads)
  (ice-9 futures)
  ;; let-values form
  (srfi srfi-11))


(define-values (in out)
   (match-let ([(in . out) (pipe)])
     ;; make out line buffered
     ;; (setvbuf out 'none)
     (values in out)))


(define seconds
   (λ (s)
     (* s (expt 10 6))))


(define endless-writer
   (λ (out)
     (let loop ()
       (simple-format #t "writer: writing message to output port\n")
       (put-string out "Hello!\n")
       ;; forcing the output should be unnecessary
       ;; (force-output out)
       (usleep (seconds 1))
       (loop))
     'never))


(define line-reader
   (lambda* (in-port out-port)
     "Read from an IN-PORT and write to OUT-PORT."
     (let loop ([line (get-line in-port)])
       (simple-format #t "reader: reading from in-port\n")
       (unless (eof-object? line)
         (put-string out-port line)
         (loop (get-line in-port))))))


;; Start writing endlessly.
(define writer-future (future (endless-writer out)))


;; Read from in-port, which should be the corresponding one to the
;; out-port, to which the endless-writer writes its output. Output to
;; the current output port, so that the output is visible. Read some
;; number of bytes at once. Limits the amount of memory needed for the
;; string.

(reader in (current-output-port) #:bytes-count 16)

;; That does not output anything.

(line-reader in (current-output-port))

;; That does not output anything.
~~~~

But:

~~~~
(call-with-input-string "Test!\n"
   (lambda (in)
     (line-reader in (current-output-port))))
~~~~

Does output things.

So I am thinking my endless writer must be wrong. But I cannot figure out what 
is wrong. Or maybe I am misunderstanding how the in and out port of (pipe) 
correspond.

How can I make this work?

Also side question: Is this usage of futures "OK", or should I be using threads? 
Thought futures are more lightweight than threads in this case.

Regards,
Zelphir

-- 
repositories:https://notabug.org/ZelphirKaltstahl


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-04-11 21:13 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-11 21:13 Concurrently write (out) and read (in) from ports Zelphir Kaltstahl

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).