[plt-scheme] Need low-level help: blocking on reading from serial port in Windows

From: Nadeem Abdul Hamid (nadeem at acm.org)
Date: Thu Oct 22 18:10:19 EDT 2009

Hello all,

I'm working on a Scheme interface to some robots and am having issues  
with reading from a serial port (really a wireless Bluetooth  
connection) on Windows. Basically, I need help writing a function that  
efficiently reads data from the port (without running into deadlock  
apparently). Here's the function in question; it's supposed to read a  
specified number of bytes from the input port in a "bot" structure and  
return them in a list:

   ;; raw-read : number bot -> (listof byte)
   (define (raw-read n a-bot)
     ;(printf " raw-read")
     (local (;; read-aux : (listof byte) number port -> (listof byte)
             (define (read-aux acc n in)
               ;(sleep (/ LATENCY 1000))
               ;(printf ".~a" acc)
                 [(= n 0) acc]
                    [(byte-ready? in) (read-aux (cons (read-byte in)  
                                                (- n 1) in)]
                    [else (read-aux acc n in)])]))
             (define r (reverse (read-aux empty n (bot-in-port a- 
       ;(printf " done: ~a\n" r)

First, everything works fine beautifully on Mac OS X. Then I went to  
try this on Windows XP (using PLT Scheme 4.2.2) and it would hang in  
this function. I've finally figured out that if I uncomment the  
"sleep" statement, then it does *not* hang. However, that makes  
performance very sluggish (even though LATENCY is defined as .01). So  
I'm wondering if without the sleep there is some sort of deadlock  
happening with the byte-ready? function? I suppose I could keep a  
counter and only "sleep" every 100 or 1000 failures of the byte-ready?  
condition, but does anyone have suggestions for a better way to do  
this? To tell the truth, I don't remember why I used byte-ready? to  
begin with -- in the morning I'll try without it and see what happens  
by just letting "read-byte" block until there's data.

The port in the "bot" structure was opened using:
    (open-input-output-file portname #:mode 'binary #:exists 'update)
where on windows portname is something like "\\\\.\\COM10".

Thanks in advance for suggestions, comments. I'm still a Scheme newbie  
so welcome any criticisms :-)

--- nadeem

Posted on the users mailing list.