
Einar Karttunen wrote:
On 30.01 12:20, Simon Marlow wrote:
How would you interrupt the FFI call when the timeout expired? pthread_cancel(), maybe?
That is one solution. Just letting it running and returning is "good enough" for most things. One common thing would be network related functions if implemented in a blocking way (over various C libraries). They usually do need timeouts and are blocking FFI calls.
I think it would be wrong to leave the FFI call running and still deliver the exception to the thread. Wrong because it leads to surprising behaviour: if the blocked call has a side effect, e.g. a write(), then the side-effect may still heppen, despite the fact that the Haskell thread has been interrupted by the timeout. And wrong because it's not possible to implement it in GHC, at least for bound threads: the OS thread making the foreign call is the only one that can execute the Haskell thread. So that leaves pthread_cancel(). Unfortunately pthread_cancel() isn't really an exception - it can be caught, but the handler is for cleaning up only, it can't continue. So this doesn't let us interrupt FFI calls either. Any other suggestions? My take on this is that if you want to make an interruptible FFI call, you make it in a separate thread, and ensure that if it continues to execute after the parent has received an exception, then this is benign. This is essentially what the IO manager thread in the GHC IO library does: any thread blocked on I/O can be interrupted by a signal, because it is the IO manager thread performing the FFI call. Cheers, Simon