At Fri, 17 Jul 2015 16:58:50 +0200, mazert wrote:
> Le 17/07/2015 16:16, Matthias Felleisen a écrit :
> > This actually works. But I am not sure why you'd want to do something like
> that.
>
> Ah yes, letrec is what I was looking for :) . The goal was to test a
> port with a specific timeout (here I set it to two for dev purposes, but
> 10 is better). I rewrited foo with better comments below.
>
> Just to be sure, I cant have the prompt return without using a
> (thread-wait thd) function ?
>
> 1) The port is not good so b kills a, then b ends. The program continue.
> 2) But if I set (thread-wait a), b kills a, then b ends. As a was
> killed, it is considered as terminated so it is the same as 1) ?
Yes.
Beware, though, that there's a race condition here:
> #lang racket
>
> (define (foo)
> (letrec ([a (thread (λ ()
> (let-values ([(p-in p-out) (tcp-connect
> "
smtp.gmail.com" 5887)])
> (printf "Server port is good")
> (kill-thread b))))]
> [b (thread (λ ()
> (displayln `(hello world))
> (sleep 2)
> (printf "Server port is not good")
> (kill-thread a)))])
> (thread-wait b)))
It's possible (but unlikely) for the thread bound to `a` to complete
and try to kill `b` before the variable `b` is initialized.
Here's what I'd do:
* Create a custodian to manage the thread, and shut the custodian down
instead of killing the thread. That way, in addition to killing the
thread, any network resources are also released.
* Instead of starting a timer thread, use `sync/timeout`.
(define (foo)
(define c (make-custodian))
(define t (parameterize ([current-custodian c])
(thread
(λ ()
(let-values ([(p-in p-out)
(tcp-connect "
smtp.gmail.com" 5887)])
(printf "Server port is good"))))))
(displayln `(hello world))
(unless (sync/timeout 2 t) ; produces #f on timeout
(printf "Server port is not good")
(custodian-shutdown-all c)))