[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