[racket] How to wait for tcp-accpt-evt unless the listener is or has been closed?

From: Erich Rast (erich at snafu.de)
Date: Thu Sep 13 14:17:55 EDT 2012

Hi all,

I have a question about tcp-listener. I've implemented a simple
filetransfer protocol whose main listener loop is this:

(define (start-listen local-port save-path from-ip progress-proc final-proc
                      [timeout 60.0] [file-table (make-hash)])
  (define listener (tcp-listen local-port 1 #t #f))
  (thread
   (lambda ()
     (progress-proc 'listening save-path 0)
     (let loop ((in-out-ports (sync/enable-break (tcp-accept-evt listener))))
       (receive-file (first in-out-ports) (second in-out-ports) 
          save-path progress-proc final-proc file-table timeout)
       (loop (sync/enable-break (tcp-accept-evt listener))))))
  listener)

In my tests, after transfering a file I call (just for fun) stop-listen:

(define (stop-listen listener)
  (tcp-close listener))

and the result is an exception. The problem is, how do I end the loop in the above thread when the listener is closed? Obviously,

(when (port-closed? (first in-out-ports))
  (loop (sync/enable-break (tcp-accept-evt listener))))

does not have the desired effect, because sync/enable-break is already waiting, so when the port is closed tcp-accept-evt correctly raises a network exception. Basically, I need a synchronizable event that yields #f if the listener is closed, the opened ports otherwise. But how? There is not even a tcp-listener-closed? method.

Any suggestions?

Best,

Erich

Posted on the users mailing list.