Hi Ron,
Thanks for that - but I can only see #dataAvailable for Sockets, not for FileStream (named pipes). I think the same kind of thing is available for pipes (you can do `pipe size` to see how much data is there), but it still doesn't wait. I'm trying to avoid a busy loop waiting for the data - like this:
start := DateAndTime millisecondClockValue.
(pipe size < 32) & (DateAndTime millisecondClockValue - start < 3000) ifTrue: [
(Delay forMilliseconds 50) wait.
]
pipe size = 32 ifTrue: [
"Get data"
] ifFalse: [
"Deal with timeout"
]
The shorter the 'wait', the more responsive the code is to data arriving on the pipe, but the more CPU it will use as it spins round the loop. The longer the 'wait', the more lag it has for data coming back. That's what I'm trying to avoid by blocking on the read, but with a way to escape after some timeout.
I'm guessing the call to 'pipe next:' is a primitive, and blocks there, which is why valueWithin:onTimeout: doesn't return after the timeout, but does eventually return the correct answer. So, I'm guessing I'll have to do something like this:
- Set up a semaphore
- Fork the blocking read process, which will signal the semaphore if it ever returns its 32 bytes
- In the main thread, wait for up to 3 seconds for the semaphore to be signalled
- If the semaphore times out, kill the forked process
Obviously there's a potential race at the end there, but the worst case is we throw away data which was returned at the last moment. Is there anything else you can see wrong with this approach?
Thanks,
Dave