[Haskell-cafe] ForeignPtrs, Finalizers and thread-local storage

Justin Paston-Cooper paston.cooper at gmail.com
Tue Jul 3 10:10:12 UTC 2018


glpk-hs defines a binding to glpk, a linear programme library. A linear
programme is created by calling `glp_create_prob` and deleted by calling
`glp_delete_prob`. These two C functions manage memory themselves using
thread-local storage.

They are called by glpk-hs using the foreign function interface in the
following code. Note that glpDelProb and glpCreateProb are imported foreign
functions.

runGLPK :: GLPK a -> IO a
runGLPK m = do  lp <- newForeignPtr glpDelProb =<< glpCreateProb
                withForeignPtr lp (execGLPK m)

(
https://github.com/jyp/glpk-hs/blob/master/src/Data/LinearProgram/GLPK/Types.hs
)

It seems that sometimes the finaliser is called in a thread different to
the one where glp_create_prob is called. This leads to glpk aborting with a
dynamic memory allocation error when tries to de-allocate the linear
programme in the wrong thread-local storage, which has never seen that
programme.

Given that the ForeignPtr is used only in runGLPK, runGLPK could of course
be fixed by using Control.Concurrent.bracket instead. However, I'm
interested to know whether there is a solution to this problem.

I'm only assuming that the finaliser sometimes runs in a different thread.
If this is indeed the case, then is there any way to ensure that a
finaliser runs in the thread where the pointer is created?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20180703/ca007c20/attachment.html>


More information about the Haskell-Cafe mailing list