
several ideas
a) you can use forkOS to run the ffi call and the the subsequent errno
value checking in a pinned OS thread so you can guarantee you can access
the thread local storage
b) you could have a CallManager that keeps a MVar or queue or something,
along with a handle on the forkOS thread id, and "intiialize" the forkOS
thread with a teeny worker that read from an input MVar and writes to a
result MVar (thus guarantee only one call a time)
c) something that uses these ideas together.
theres a lot of strategies you can use. but i hope this gives you a sketch
(i can spell it out more later this week if need be)
On Tue, Aug 19, 2014 at 5:36 PM, Nikolay Amiantov
Hello Cafe,
I'm using FFI to interact with a library which calls, when fail, leave the reason in some kind of "errno"-like variable which is retrived via another call. AFAIU, this is not thread-safe in Haskell even if thread-local storage is used inside the library, because Haskell uses its own thread management and the Haskell thread in the same OS thread might be switched between the actual call and the retrival of errno value. This should be somehow handled already in Haskell (errno is widely used with syscalls in Linux, for example), but the source of Foreign.C.Error suggests that this is not handled in any way at all. For example, throwErrnoIf is implemented as such:
throwErrno loc = do errno <- getErrno ioError (errnoToIOError loc errno Nothing Nothing)
throwErrnoIf pred loc f = do res <- f if pred res then throwErrno loc else return res
So, the question is: how is it ensured that this block is "atomic" in sense that at most one Haskell thread computes this whole function at every moment in every OS thread?
Thanks for any explanations! (And sorry if my English is poor)
Nikolay. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe