Re: experimental control.timeout/with-timeout
Shiro Kawai <[email protected]> Mon, 20 Jan 2025 23:21:43 -1000
| Newsgroups | gmane.lisp.scheme.gauche |
|---|---|
| Message-ID | <CALN0JNECs_3eoKCfvR_+iOXqj0SCDMNeWKdvDV2moG=khC_k6w@mail.gmail.com> |
--===============7732120047683415407== Content-Type: multipart/alternative; boundary="00000000000069f905062c33e85a" --00000000000069f905062c33e85a Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Good point. Safe termination of threads has always been a concern. I vaguely remember I once tried a condition mechanism (e.g. termination sends a special exception to a thread, and the thread rewinds dynamic handlers) but didn't work---the condition mechanism can intercept it. Since the after-thunk of the dynamic handler is free to invoke previously captured continuations, we can't guarantee that it terminates. We may still introduce rewinding of dynamic handlers, just prohibit certain control transfers from them. Another option is to have a separate cleanup stack like pthread_cleanup_push/pop. Current termination semantics is very hard to use safely, anyway, so it may be good to dive and fix this now in some way. On Mon, Jan 20, 2025 at 11:02=E2=80=AFPM Jens Thiele <[email protected]> wrote= : > Hi, > > very likely you are already aware of this: > > some "real-world" examples of imho unexpected behaviour with > control.timeout/with-timeout (one could argue pmap with fully concurrent > mapper + timeout also has this problem) > > 1) stop motor isn't printed: > gosh> (with-timeout > (lambda() (unwind-protect (begin (print "start motor") > (sys-sleep 10)) > (print "stop motor"))) 1) > start motor > #f > > 2) timer isn't stopped: > gosh> (use gauche.time) > gosh> (let1 tc (make <real-time-counter>) > (guard (e [else #?=3De]) > (with-timeout (lambda() (with-time-counter tc > (sys-sleep 10) > (error "foo"))) > 1)) > (time-counter-value tc)) > 0 > > looks like guile does run dynamic-wind post thunks before thread > termination (I don't know whether this is really a good idea?): > > test.sh: > ,---- > | #!/bin/bash -xe > | cat > test.scm <<EOF > | (cond-expand > | (guile > | (use-modules (srfi srfi-18)) > | (use-modules (srfi srfi-34))) > | (gauche > | (use gauche.threads) > | (define sleep sys-sleep))) > | (let ((t (thread-start! > | (make-thread (lambda() > | (dynamic-wind > | (lambda _ #t) > | (lambda() > | (display "start motor\n") > | (sleep 10)) > | (lambda() > | (display "stop motor\n")))))))) > | (sleep 1) > | (thread-terminate! t) > | (guard (e (else (display e) (newline))) > | (thread-join! t))) > | EOF > | guile -s test.scm > | gosh test.scm > `---- > > ./test.sh > + cat > + guile -s test.scm > [...] > start motor > stop motor > #<&terminated-thread-exception> > + gosh test.scm > start motor > #<terminated-thread-exception: #<thread #f (1) terminated ... > > jens > > > _______________________________________________ > Gauche-devel mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/gauche-devel > --00000000000069f905062c33e85a Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr">Good point.<div><br></div><div>Safe termination of threads= has always been a concern.=C2=A0 I vaguely remember I once tried a conditi= on mechanism (e.g. termination sends a special exception to a thread, and t= he thread rewinds dynamic handlers) but didn't work---the condition mec= hanism can intercept it.=C2=A0 Since the after-thunk of the dynamic handler= is free to invoke previously captured continuations, we can't guarante= e that it terminates.</div><div><br></div><div>We may still introduce rewin= ding of dynamic=C2=A0handlers, just prohibit certain control transfers from= them.=C2=A0 Another option is to have a separate cleanup=C2=A0stack like p= thread_cleanup_push/pop.=C2=A0 Current termination semantics is very hard t= o use safely, anyway, so it may be good to dive and fix this now in some wa= y.</div><div><br></div><div><br></div><div><br></div><div><br></div><div><b= r></div></div><br><div class=3D"gmail_quote gmail_quote_container"><div dir= =3D"ltr" class=3D"gmail_attr">On Mon, Jan 20, 2025 at 11:02=E2=80=AFPM Jens= Thiele <<a href=3D"mailto:[email protected]">[email protected]</a>> wrote:= <br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8= ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi,<br> <br> very likely you are already aware of this:<br> <br> some "real-world" examples of imho unexpected behaviour with<br> control.timeout/with-timeout (one could argue pmap with fully concurrent<br= > mapper + timeout also has this problem)<br> <br> 1) stop motor isn't printed:<br> gosh> (with-timeout<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 (lambda() (unwind-protect (begin (print "s= tart motor")<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(s= ys-sleep 10))<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (print "stop motor"= ))) 1)<br> start motor<br> #f<br> <br> 2) timer isn't stopped:<br> gosh> (use gauche.time)<br> gosh> (let1 tc (make <real-time-counter>)<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 (guard (e [else #?=3De])<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(with-timeout (lambd= a() (with-time-counter tc<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(s= ys-sleep 10)<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(e= rror "foo")))<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A01))<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 (time-counter-value tc))<br> 0<br> <br> looks like guile does run dynamic-wind post thunks before thread<br> termination (I don't know whether this is really a good idea?):<br> <br> test.sh:<br> ,----<br> | #!/bin/bash -xe<br> | cat > test.scm <<EOF<br> | (cond-expand<br> |=C2=A0 =C2=A0(guile<br> |=C2=A0 =C2=A0 =C2=A0(use-modules (srfi srfi-18))<br> |=C2=A0 =C2=A0 =C2=A0(use-modules (srfi srfi-34)))<br> |=C2=A0 =C2=A0(gauche<br> |=C2=A0 =C2=A0 =C2=A0(use gauche.threads)<br> |=C2=A0 =C2=A0 =C2=A0(define sleep sys-sleep)))<br> | (let ((t (thread-start!<br> |=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(make-thread (lambda()<br> |=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 (dynamic-wind<br> |=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0(lambda _ #t)<br> |=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0(lambda()<br> |=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(display "start motor\n")<br> |=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(sleep 10))<br> |=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0(lambda()<br> |=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(display "stop motor\n"))))))))<br= > |=C2=A0 =C2=A0(sleep 1)<br> |=C2=A0 =C2=A0(thread-terminate! t)<br> |=C2=A0 =C2=A0(guard (e (else (display e) (newline)))<br> |=C2=A0 =C2=A0 =C2=A0 =C2=A0 (thread-join! t)))<br> | EOF<br> | guile -s test.scm<br> | gosh test.scm<br> `----<br> <br> ./test.sh<br> + cat<br> + guile -s test.scm<br> [...]<br> start motor<br> stop motor<br> #<&terminated-thread-exception><br> + gosh test.scm<br> start motor<br> #<terminated-thread-exception: #<thread #f (1) terminated ...<br> <br> jens<br> <br> <br> _______________________________________________<br> Gauche-devel mailing list<br> <a href=3D"mailto:[email protected]" target=3D"_blank">Gau= [email protected]</a><br> <a href=3D"https://lists.sourceforge.net/lists/listinfo/gauche-devel" rel= =3D"noreferrer" target=3D"_blank">https://lists.sourceforge.net/lists/listi= nfo/gauche-devel</a><br> </blockquote></div> --00000000000069f905062c33e85a-- --===============7732120047683415407== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline --===============7732120047683415407== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Gauche-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/gauche-devel --===============7732120047683415407==--