Rocksolid Light

Welcome to RetroBBS

mail  files  register  newsreader  groups  login

Message-ID:  

Love sometimes expresses itself in sacrifice. -- Kirk, "Metamorphosis", stardate 3220.3


devel / comp.lang.lisp / Re: Stream handling: listen returns T, but read-line hangs

SubjectAuthor
* Stream handling: listen returns T, but read-line hangsAxel Reichert
+* Re: Stream handling: listen returns T, but read-line hangsMadhu
|`- Re: Stream handling: listen returns T, but read-line hangsAxel Reichert
`* Re: Stream handling: listen returns T, but read-line hangsManuel Giraud
 +* Re: Stream handling: listen returns T, but read-line hangsMadhu
 |`- Re: Stream handling: listen returns T, but read-line hangsManuel Giraud
 `- Re: Stream handling: listen returns T, but read-line hangsAxel Reichert

1
Stream handling: listen returns T, but read-line hangs

<m21r60sj3q.fsf@axel-reichert.de>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=16659&group=comp.lang.lisp#16659

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: mail@axel-reichert.de (Axel Reichert)
Newsgroups: comp.lang.lisp
Subject: Stream handling: listen returns T, but read-line hangs
Date: Tue, 07 Sep 2021 13:47:21 +0200
Organization: A noiseless patient Spider
Lines: 66
Message-ID: <m21r60sj3q.fsf@axel-reichert.de>
Mime-Version: 1.0
Content-Type: text/plain
Injection-Info: reader02.eternal-september.org; posting-host="16fac31c8b15d9806b01b1fcaf5a5806";
logging-data="32253"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX187uXUJPWGiM4AFN0EKvPF2sb5tOGw6Xro="
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (darwin)
Cancel-Lock: sha1:suFAW2t3r8bel6BuPEcelTMUg9E=
sha1:MeBCx7KJVqfrhf+vyp0UVE1wbLE=
 by: Axel Reichert - Tue, 7 Sep 2021 11:47 UTC

Hi,

hopefully I have stripped the problematic code to something
representative but simple enough ...

I (using SBCL and Slime on macOS) have the following:

(defparameter *call-for-action*
(uiop:launch-program "nc -l 11111" :input :stream :output :stream))

to listen on some example port. Some third party application writes
lines to this stream, upon which I want to act according to the content
of the line.

Since only occasionally a new line arrives on the stream and I do not
want to get stuck if nothing happens (this can be taken as a sign that
the third party application is done with its business), I am listening
to the port. If nothing is there, I listen again after 10 s. If
something is there (on first or second try), I read it, and the action
returns a non-nil value.

(defun handle-one-action ()
(let ((stream (uiop:process-info-output *call-for-action*)))
(when (or (listen stream)
(progn (sleep 10) (listen stream)))
(read-line stream nil)
(some-action-returning-non-nil))))

Now I am looping over this:

(loop (unless (handle-one-action) (return)))

The loop works fine and acts "immediately" upon line after line, until
the third party application is done (there are other ways to confirm
this). Then the loop gets stuck (I waited for more than 10 seconds ...
(-:).

While stepping through the debugger and evaluating forms, I was able to
find out that

(listen stream)

returns T even after the app is done. However, neither a read-line nor a
read-char were able to read anything and thus blocked. When I aborted
the debugger and tried

(loop (unless (handle-one-action) (return)))

again, it returned as expected after 10 seconds. The debugger revealed
that now before the read-line evaluating

(listen stream)

returned NIL.

So I understand why my code hangs, but not why "listen" detects something
when there seems to be nothing.

Any hints on how I can ensure a robust exit from the loop? Pointers much
appreciated!

Axel
--
-X- | in memoriam John Conway
--X | 1937-2020
XXX | A glider from his "Game of Life"

Re: Stream handling: listen returns T, but read-line hangs

<m3czpjzidm.fsf@leonis4.robolove.meer.net>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=16660&group=comp.lang.lisp#16660

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: enometh@meer.net (Madhu)
Newsgroups: comp.lang.lisp
Subject: Re: Stream handling: listen returns T, but read-line hangs
Date: Wed, 08 Sep 2021 12:03:25 +0530
Organization: Motzarella
Lines: 88
Message-ID: <m3czpjzidm.fsf@leonis4.robolove.meer.net>
References: <m21r60sj3q.fsf@axel-reichert.de>
Mime-Version: 1.0
Content-Type: text/plain
Injection-Info: reader02.eternal-september.org; posting-host="e825976da9a9add52f8a82cda2b59246";
logging-data="23644"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18ovuu1yc5U7xtUVHXM5gMZc1VCU1+W+dM="
Cancel-Lock: sha1:bRUnrzq+R8m4JEn+uWXd4H859bA=
sha1:8OR8kpd8P0cT4HBLwcyoj1o6eSE=
 by: Madhu - Wed, 8 Sep 2021 06:33 UTC

* Axel Reichert <m21r60sj3q.fsf@axel-reichert.de> :
Wrote on Tue, 07 Sep 2021 13:47:21 +0200:
> hopefully I have stripped the problematic code to something
> representative but simple enough ...
>
> I (using SBCL and Slime on macOS) have the following:

[No sbcl/uiop here - so consume the following with a pinch of salt]

> (defparameter *call-for-action*
> (uiop:launch-program "nc -l 11111" :input :stream :output :stream))
>
> to listen on some example port. Some third party application writes
> lines to this stream, upon which I want to act according to the content
> of the line.

[snip]

> (defun handle-one-action ()
> (let ((stream (uiop:process-info-output *call-for-action*)))
> (when (or (listen stream)
> (progn (sleep 10) (listen stream)))
> (read-line stream nil)
> (some-action-returning-non-nil))))
>
> Now I am looping over this:
> (loop (unless (handle-one-action) (return)))
> The loop works fine and acts "immediately" upon line after line, until
> the third party application is done (there are other ways to confirm
> this). Then the loop gets stuck (I waited for more than 10 seconds ...
> (-:).
>
> While stepping through the debugger and evaluating forms, I was able to
> find out that
>
> (listen stream)
>
> returns T even after the app is done.

When the connection to netcat from the remote host is dropped, netcat
exits. The netcat process is dead. (uiop:process-alive-p
*call-for-action*) would return NIL.

But the streams which the Lisp has created may still be open - they may
have unread data and can still be read. So LISTEN returns T

PEEK-CHAR may return T and READ-CHAR may return a value. But once the
characters are read off the stream you should get an EOF condition on
the stream you are reading and then LISTEN should yield NIL.

READ-LINE should encouter EOF in case there isn't a newline on the
stream.

I've checked now and this is how CCL behaves. LISTEN returns T until
there is unread data - when it hits EOF it returns NIL

[Note - you can't inspect the ccl streams from another thread unless you
call CCL:RUN-PROGRAM with :SHARING :EXTERNAL stream arguments]

> However, neither a read-line nor a
> read-char were able to read anything and thus blocked. When I aborted
> the debugger and tried
>
> (loop (unless (handle-one-action) (return)))
>
> again, it returned as expected after 10 seconds. The debugger revealed
> that now before the read-line evaluating
>
> (listen stream)
>
> returned NIL.

That means there is no more data now and the stream buffer has been
emptied.

> So I understand why my code hangs, but not why "listen" detects something
> when there seems to be nothing.

I don't think this matches my experience.

> Any hints on how I can ensure a robust exit from the loop? Pointers much
> appreciated!

I would ditch this whole approach (using sleep 10, etc.) - and try to
use iolib streams but that i suspect that won't be more any more robust,
cross platform.

Re: Stream handling: listen returns T, but read-line hangs

<87zgsn8nwp.fsf@elite.giraud>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=16661&group=comp.lang.lisp#16661

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!i2pn.org!aioe.org!TwdCcQmhgaJnyAo4a0LfYg.user.46.165.242.75.POSTED!not-for-mail
From: manuel@ledu-giraud.fr (Manuel Giraud)
Newsgroups: comp.lang.lisp
Subject: Re: Stream handling: listen returns T, but read-line hangs
Date: Wed, 08 Sep 2021 10:36:06 +0200
Organization: Aioe.org NNTP Server
Message-ID: <87zgsn8nwp.fsf@elite.giraud>
References: <m21r60sj3q.fsf@axel-reichert.de>
Mime-Version: 1.0
Content-Type: text/plain
Injection-Info: gioia.aioe.org; logging-data="39602"; posting-host="TwdCcQmhgaJnyAo4a0LfYg.user.gioia.aioe.org"; mail-complaints-to="abuse@aioe.org";
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (berkeley-unix)
X-Notice: Filtered by postfilter v. 0.9.2
Cancel-Lock: sha1:Xxl1xQ0VRsdCVxkmtg5y/TBJZeY=
 by: Manuel Giraud - Wed, 8 Sep 2021 08:36 UTC

Hi Axel,

I do not follow what you are trying to do. Your *call-for-action*
process is a netcat server already waiting for connections and handling
clients as netcat do. So I don't know what a listen to its stream from
sbcl will do.

Here is an complete (no external netcat involved) usocket example of a
timing out server that might be what you want:
--8<---------------cut here---------------start------------->8---
(asdf:load-system :usocket)

(defun myserver (&optional (port 11111) (timeout 10))
(let ((connections (list (usocket:socket-listen usocket:*wildcard-host* port
:reuse-address t))))
(unwind-protect
(loop for sockets = (usocket:wait-for-input connections :ready-only t
:timeout timeout)
while sockets do
(dolist (ready sockets)
(cond ((usocket:stream-server-usocket-p ready) ;; this is a new connection to me
(let ((client (usocket:socket-accept ready)))
(push client connections)))
(t ;; there is message from some client
(setf connections (remove ready connections))
(handle-client ready)))))
(dolist (c connections) (usocket:socket-close c)))))

(defun handle-client (socket)
(let ((stream (usocket:socket-stream socket)))
(unwind-protect
(when (listen stream)
(format t "~&message: ~a~%" (read-line stream)))
(usocket:socket-close socket))))
--8<---------------cut here---------------end--------------->8---

Best regards,
--
Manuel Giraud

Re: Stream handling: listen returns T, but read-line hangs

<m3fsufid5k.fsf@leonis4.robolove.meer.net>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=16662&group=comp.lang.lisp#16662

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: enometh@meer.net (Madhu)
Newsgroups: comp.lang.lisp
Subject: Re: Stream handling: listen returns T, but read-line hangs
Date: Wed, 08 Sep 2021 15:48:15 +0530
Organization: Motzarella
Lines: 12
Message-ID: <m3fsufid5k.fsf@leonis4.robolove.meer.net>
References: <m21r60sj3q.fsf@axel-reichert.de> <87zgsn8nwp.fsf@elite.giraud>
Mime-Version: 1.0
Content-Type: text/plain
Injection-Info: reader02.eternal-september.org; posting-host="cfebe241e1f9cd50a5ab88f8c5a94f58";
logging-data="13359"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+Fitsb4qKvxz+QMwqSWsih7SG4vLgs5R4="
Cancel-Lock: sha1:NtsiSdPs6F06skNId7Jfl6ibAqM=
sha1:HyTd4umtwEH9FoRCO7r0+UWQ2aY=
 by: Madhu - Wed, 8 Sep 2021 10:18 UTC

* Manuel Giraud <87zgsn8nwp.fsf@elite.giraud> :
Wrote on Wed, 08 Sep 2021 10:36:06 +0200:

> I do not follow what you are trying to do. Your *call-for-action*
> process is a netcat server already waiting for connections and handling
> clients as netcat do. So I don't know what a listen to its stream from
> sbcl will do.

It's common-lisp's LISTEN on lisp streams

http://www.lispworks.com/documentation/lw71/CLHS//Body/f_listen.htm

Re: Stream handling: listen returns T, but read-line hangs

<m2lf46eur2.fsf@axel-reichert.de>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=16663&group=comp.lang.lisp#16663

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: mail@axel-reichert.de (Axel Reichert)
Newsgroups: comp.lang.lisp
Subject: Re: Stream handling: listen returns T, but read-line hangs
Date: Wed, 08 Sep 2021 21:24:01 +0200
Organization: A noiseless patient Spider
Lines: 31
Message-ID: <m2lf46eur2.fsf@axel-reichert.de>
References: <m21r60sj3q.fsf@axel-reichert.de>
<m3czpjzidm.fsf@leonis4.robolove.meer.net>
Mime-Version: 1.0
Content-Type: text/plain
Injection-Info: reader02.eternal-september.org; posting-host="4819cb0fbf2dd18ec77833ac6d778a86";
logging-data="7480"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18eh3+2f9b54oJ1CGT6DObyhF2MjslZNQs="
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (darwin)
Cancel-Lock: sha1:zitnWnlldtMzbreiqYFz/8Y6nII=
sha1:MXVCOTbxZOUQfqlBnGrmJc3vXIg=
 by: Axel Reichert - Wed, 8 Sep 2021 19:24 UTC

Madhu <enometh@meer.net> writes:

> When the connection to netcat from the remote host is dropped, netcat
> exits. The netcat process is dead. (uiop:process-alive-p
> *call-for-action*) would return NIL.

This is not the case. It returns T.

> PEEK-CHAR may return T

Yes, in a sense. In fact it returned #\Nul, which screwed up things
further downstream. After a read-char of #\Nul, (listen ...) returned
NIL. Now I grab that NUL char and listen again.

So there is progress: It does not hang any more, but I am still
struggling with the correct return values in my loop. But not today.

Thanks for the reminder on the existence of peek-char!

> I would ditch this whole approach (using sleep 10, etc.) - and try to
> use iolib streams

Perhaps. Manuel's post pointed in the same direction.

Thanks for now, I will conduct some trials.

Axel
--
-X- | in memoriam John Conway
--X | 1937-2020
XXX | A glider from his "Game of Life"

Re: Stream handling: listen returns T, but read-line hangs

<m2h7eueujk.fsf@axel-reichert.de>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=16664&group=comp.lang.lisp#16664

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: mail@axel-reichert.de (Axel Reichert)
Newsgroups: comp.lang.lisp
Subject: Re: Stream handling: listen returns T, but read-line hangs
Date: Wed, 08 Sep 2021 21:28:31 +0200
Organization: A noiseless patient Spider
Lines: 23
Message-ID: <m2h7eueujk.fsf@axel-reichert.de>
References: <m21r60sj3q.fsf@axel-reichert.de> <87zgsn8nwp.fsf@elite.giraud>
Mime-Version: 1.0
Content-Type: text/plain
Injection-Info: reader02.eternal-september.org; posting-host="4819cb0fbf2dd18ec77833ac6d778a86";
logging-data="7480"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/ZlJyPNGFxTqjH+JanlyUHCeqzRnJDTow="
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (darwin)
Cancel-Lock: sha1:mm0dAhyUhVIzHPAGec47JeM1FGE=
sha1:P54CO6R9LBMg04aPkHyNC5KSAV8=
 by: Axel Reichert - Wed, 8 Sep 2021 19:28 UTC

Manuel Giraud <manuel@ledu-giraud.fr> writes:

> I do not follow what you are trying to do. Your *call-for-action*
> process is a netcat server already waiting for connections and handling
> clients as netcat do.

It seems I was losing the forest for the trees. You mean I should
instead "directly" (in Lisp) listen to the third party application? True
enough ...

> Here is an complete (no external netcat involved) usocket example of a
> timing out server that might be what you want:

Sounds good, many thanks, I will give it a try if my "new hope" (see
reply to Madhu) fails.

Best regards

Axel
--
-X- | in memoriam John Conway
--X | 1937-2020
XXX | A glider from his "Game of Life"

Re: Stream handling: listen returns T, but read-line hangs

<875yv6jesm.fsf@elite.giraud>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=16665&group=comp.lang.lisp#16665

  copy link   Newsgroups: comp.lang.lisp
Path: i2pn2.org!i2pn.org!aioe.org!TwdCcQmhgaJnyAo4a0LfYg.user.46.165.242.75.POSTED!not-for-mail
From: manuel@ledu-giraud.fr (Manuel Giraud)
Newsgroups: comp.lang.lisp
Subject: Re: Stream handling: listen returns T, but read-line hangs
Date: Sun, 12 Sep 2021 11:58:49 +0200
Organization: Aioe.org NNTP Server
Message-ID: <875yv6jesm.fsf@elite.giraud>
References: <m21r60sj3q.fsf@axel-reichert.de> <87zgsn8nwp.fsf@elite.giraud>
<m3fsufid5k.fsf@leonis4.robolove.meer.net>
Mime-Version: 1.0
Content-Type: text/plain
Injection-Info: gioia.aioe.org; logging-data="41921"; posting-host="TwdCcQmhgaJnyAo4a0LfYg.user.gioia.aioe.org"; mail-complaints-to="abuse@aioe.org";
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (berkeley-unix)
Cancel-Lock: sha1:6InrtSApcatV7aHphvMHUktGb54=
X-Notice: Filtered by postfilter v. 0.9.2
 by: Manuel Giraud - Sun, 12 Sep 2021 09:58 UTC

Madhu <enometh@meer.net> writes:

> * Manuel Giraud <87zgsn8nwp.fsf@elite.giraud> :
> Wrote on Wed, 08 Sep 2021 10:36:06 +0200:
>
>> I do not follow what you are trying to do. Your *call-for-action*
>> process is a netcat server already waiting for connections and handling
>> clients as netcat do. So I don't know what a listen to its stream from
>> sbcl will do.
>
> It's common-lisp's LISTEN on lisp streams

Yes, I know. But my question was more what would result from a call to
CL listen on a stream that is already handled by netcat... but I may be
missing something here.
--
Manuel Giraud


devel / comp.lang.lisp / Re: Stream handling: listen returns T, but read-line hangs

1
server_pubkey.txt

rocksolid light 0.9.81
clearnet tor