ForeignPtrs, Finalizers and thread-local storage

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... ) 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?

The Control.Concurrent.bracket solution should involve
Control.Concurrent.runInBoundThread as well.
On 3 July 2018 at 11:10, Justin Paston-Cooper
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?
participants (1)
-
Justin Paston-Cooper