[Haskell-cafe] Locking of threads in one OS thread
alexander.kjeldaas at gmail.com
Wed Aug 20 12:36:27 UTC 2014
On Tue, Aug 19, 2014 at 11:36 PM, Nikolay Amiantov <nikoamia at gmail.com>
> 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
> 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?
I do not know the RTS very well, but I think this might be unsafe. If the
thread is *bound*, then *getErrno* is guaranteed to be executed on the same
thread, but otherwise no such guarantee is given.
However, reading http://blog.ezyang.com/2013/01/the-ghc-scheduler/ it might
If GC happens, "Threads are put in *front* (pushOnRunQueue) if: ... In the
threaded runtime, if a thread was interrupted because another Capability
needed to do a stop-the-world GC (see commit 6d18141d8);"
However, the same post indicates that you can force this behavior using
"Threads are put in *back* (appendToRunQueue) in the case of pre-emption,
or if it’s new; particularly, if: ...A thread was pre-empted via the
context switch flag (e.g. incoming message from another thread, the timer
fired, the thread cooperatively yielded, etc; see also  on how this
interacts with heap overflows);"
Reading errno directly after the FFI call can eliminate heap overflows, but
the async exception and timer issues still seem possible.
I would also like to see a good explanation of this.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Haskell-Cafe