ForeignPtrs, Finalizers and thread-local storage

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

ForeignPtrs, Finalizers and thread-local storage

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)


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?

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: ForeignPtrs, Finalizers and thread-local storage

Justin Paston-Cooper
The Control.Concurrent.bracket solution should involve Control.Concurrent.runInBoundThread as well.

On 3 July 2018 at 11:10, Justin Paston-Cooper <[hidden email]> wrote:
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)


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?


_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.