[gambit-list] I/O puzzle...

Marc Feeley feeley at iro.umontreal.ca
Thu Oct 30 17:18:27 EDT 2008


Puzzle... what's the bug in the following code?  See end of message  
for answer.

(define http-server-start!
   (lambda (hs stop?)
     (let ((server-port
            (open-tcp-server
             (list port-number: (server-port-number hs)
                   backlog: 128
                   reuse-address: #t
                   server-address: '#u8(127 0 0 1) ; on localhost  
interface only
                   char-encoding: 'ISO-8859-1))))
       (input-port-timeout-set! server-port 3)
       (accept-connections hs server-port stop?))))

(define accept-connections
   (lambda (hs server-port stop?)
     (let loop ()
       (let ((connection
              (read server-port)))
         (if (eof-object? connection)
             (if (stop?)
                 (close-input-port server-port)
                 (loop))
             (begin
               (if (server-threaded? hs)
                   (let ((dummy-port (open-dummy)))
                     (parameterize ((current-input-port dummy-port)
                                    (current-output-port dummy-port))
                       (thread-start!
                        (make-thread
                         (lambda ()
                           (serve-connection hs connection))))))
                   (serve-connection hs connection))
               (loop)))))))

.
.
.
.
.
.
.
.

Answer: the (input-port-timeout-set! server-port 3) is at the wrong  
place.  It sets a timeout ***3 seconds in the future***.  So after 3  
seconds have passed all calls to read in accept-connections will not  
block (and lead to a tight, CPU intensive loop).  The correct approach  
is to put the call to (input-port-timeout-set! server-port 3) just  
before the call to read.

Puzzle #2: why did Gambit chose to define timeouts that are not  
relative to the moment that an I/O function is called?

Marc




More information about the Gambit-list mailing list