Hi all,

The code below is a simple server based on the web server in the “More: Systems 
programming in Racket” tutorial.

This behavior is puzzling me:
I run the server (from the OS X Terminal) and connect a client.
After a wait, the client is disconnected by the timeout (shown in red).
I halt the server with ^C, by triggering the thunk shown in blue.
I start the server again — same way, from the Terminal — and get an “Address 
already in use” error.

This behavior happens consistently.

What’s perplexing is that if I close the connection from the client side 
instead of waiting in step (2) — in which case I understand the bold purple 
expression to be closing the connection — I consistently do not get an error.

I’m puzzled because my current understanding is that the two identical calls to 
custodian-shutdown-all should both be shutting down the same threads and I/O 
ports that were created under the custodian cust — and that even if this 
weren’t the case, the (custodian-shutdown-all main-cust) call should be 
cleaning up those same resources (in addition to shutting down the listener), 
because cust is subordinate to main-cust.

So my question is: What difference between the two cases accounts for the 
different behavior?


;;;;; Example server ;;;;;

#lang racket/base

(require racket/tcp)

(define (serve port)
  (define main-cust (make-custodian))
  (parameterize ([current-custodian main-cust])
    (define listener (tcp-listen port))
    (define (loop) (accept/handle listener) (loop))
    (thread loop)
    ;; Hook to shutdown the server:
    (lambda ()
      (printf "Exiting...~n")
      (custodian-shutdown-all main-cust)
      (exit 0))))

(define (accept/handle l)
  (define cust (make-custodian))
  (parameterize ([current-custodian cust])
    (define-values (in out) (tcp-accept l))
    (thread (lambda ()
              (let loop ([s (read-line in)])
                (unless (eof-object? s)
                  (fprintf out "Got it.~n")
                  (flush-output out)
                  (loop (read-line))))
              (custodian-shutdown-all cust)))
    ;; Timeout:
    (thread (lambda () (sleep 5) (custodian-shutdown-all cust)))))

(define stop (serve 9001))

(with-handlers ([exn:break? (lambda (e) (stop))])
  (let loop () (sleep 10) (loop)))

You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to