It seems desirable to create a FunPtr to a top-level function just once instead of creating a new one (to the same function) whenever it's needed and dealing with its deallocation.
Am I overlooking some way to obtain the FunPtr other than foreign import ccall "wrapper"? If not, my workaround would be as in the code below. Is that safe?
type SomeCallback = CInt -> IO ()
foreign import ccall "wrapper" mkSomeCallback :: SomeCallback -> IO (FunPtr SomeCallback)
f :: SomeCallback
f i = putStrLn ("It is: "++show i)
{-# NOINLINE f_FunPtr #-}
f_FunPtr :: FunPtr SomeCallback
f_FunPtr = unsafePerformIO (mkSomeCallback f)
Edit: Verified that the "creating a new one every time" variant (main = forever (mkSomeCallback f)) does in fact leak memory if one doesn't freeHaskellFunPtr it.
This should, in principle, be safe - GHC internal code uses a similar pattern to initialize singletons such as the IO watched-handles queues. Just keep in mind that you have no control over when mkSomeCallback runs, and don't forget the NOINLINE.
Related
I inherited a code base using the following idiom, which exports and then reimports a function via the FFI:
foreign export ccall someHaskellFn :: a -> IO b
foreign import ccall "&someHaskellFn"
someHaskellFn_addr :: FunPtr (a -> IO b)
Neither the Haskell function someHaskellFn, nor the exported function is ever used; only someHaskellFn_addr is required, and is always used in an IO context:
-- frob :: FunPtr (a -> IO b) -> IO ()
frob someHaskellFn_addr
I'm wondering whether this has any advantages over using a wrapper function:
foreign import ccall "wrapper"
mkWrapper :: (a -> IO b) -> IO (FunPtr (a -> IO b))
-- Function pointer to someHaskellFn, never freed
someHaskellFnPtr = mkWrapper someHaskellFn
frob =<< someHaskellFnPtr
The documentation for Foreign.Ptr mentions these two methods to create a value of type FunPtr a:
A value of type FunPtr a may be a pointer to a foreign function,
either returned by another foreign function or imported with a a
static address import like
foreign import ccall "stdlib.h &free"
p_free :: FunPtr (Ptr a -> IO ())
or a pointer to a Haskell function created using a wrapper stub
declared to produce a FunPtr of the correct type.
It also says
Calls to wrapper stubs […] allocate storage, which should be released with freeHaskellFunPtr when no longer required.
My understanding is that the wrapper using code behaves indentical (on the Haskell side) to the export/import variant; is this correct? Are there any finer details about foreign function imports and exports which I am missing?
I have the following C function that I want to call from Haskell:
void read_params_for (property_list_t *props);
The function is supposed to receive some property_list_t and populate some values within it, so the caller then has an updated structure.
I have all the necessary wrappers for property_list_t (like Storable, etc.), but I can't figure out how to wrap this function into something like
readParamsFor :: ForeignPtr PropertyListT -> IO (ForeignPtr PropertyListT)
I tried using C2HS, and I also tried writing FFI bindings manually like:
foreign import ccall "read_params_for"
readParamsFor' :: Ptr PropertyListT -> IO ()
readParamsFor :: ForeignPtr PropertyListT -> IO (ForeignPtr PropertyListT)
readParamsFor ps = do
withForeignPtr ps $ \ps' -> do
res <- readParamsFor' ps'
pl <- newForeignPtr propertyListDestroy ps'
return pl
But in both cases, I get back my original "underpopulated" list.
How do I get an updated structure back to Haskell?
I realised that there was a bug in a C library that I wanted to use and that indeed, a simple withForeignPtr is sufficient if the bug is not there.
I'm currently trying to port parts of the Windows API to Haskell. One of the functions covered is SetConsoleCtrlHandler which registers a handler callback that is called whenever a Ctrl+C or Ctrl+Break is received from console input. So here a small sample program:
{-# LANGUAGE CPP #-}
{-# LANGUAGE ForeignFunctionInterface #-}
module Main where
import Control.Monad
import GHC.ConsoleHandler
import Foreign
import System.Win32.Process
import System.Win32.Types
foreign import ccall "wrapper"
makeHandlerPtr :: (DWORD -> IO BOOL) -> IO (FunPtr (DWORD -> IO BOOL))
foreign import stdcall "windows.h SetConsoleCtrlHandler"
c_SetConsoleCtrlHandler :: FunPtr (DWORD -> IO BOOL) -> BOOL -> IO BOOL
main :: IO ()
main = unsafeCtrl
unsafeCtrl :: IO ()
unsafeCtrl = do
ptrHandler <- makeHandlerPtr $ \d -> do
putStrLn $ "received event " ++ show d
return True
c_SetConsoleCtrlHandler ptrHandler True
forM_ [1..50] $ \_ -> sleep 100
freeHaskellFunPtr ptrHandler
safeCtrl :: IO ()
safeCtrl = do
installHandler $ Catch $ \e -> do
putStrLn $ "received event " ++ show e
forM_ [1..50] $ \_ -> sleep 100
If you compile the above program via ghc --make AsyncCallback.hs and run the program, it crashes with the following error as soon as a control event is received:
$ AsyncCallback
AsyncCallback.exe: schedule: re-entered unsafely.
Perhaps a 'foreign import unsafe' should be 'safe'?
However, compiling with the -threaded option added seems to work fine:
$ AsyncCallback
received event 0
received event 1
received event 0
Not sure why this makes it work, as I don't explicitly use threads here, and I can't see where GHC would implicitly start a new thread.
Asking earlier about this on #haskell, someone noted that calling Haskell functions asynchronously from a C callback is inherently unsafe and that the above example just more or less coincidentally works. I was also pointed to GHC.ConsoleHandler.installHandler which seems to be a safe wrapper around SetConsoleCtrlHandler, and running the above program with main = safeCtrl indeed works fine. I tried to understand the implementation of installHandler (C-side and Haskell-side) but I don't quite get it.
The whole problem here seems to be that the callback is issued asynchronously, such that the Haskell RTS isn't "prepared" for when the callback tries to run the Haskell code. So I would like to know
How does the GHC implementation of installHandler work? What is the crucial part that makes that implementation work and my version fail?
Are there other options/general patterns how to call Haskell code asynchronously from a C callback? In this particular case, I can switch to the GHC implementation. But I may come accross similar C functions that asynchronously call back into Haskell code where I would have to write a safe binding on my own.
In the code below I manage a game, which owns a list of links.
At each step of the game, I change the game state updating the list of links modified.
As I am learning the State monad, I was trying to apply the State monad technique to this use case.
Nonetheless, at each turn, I need to get a piece of info from IO, using getLine
this gives such a code
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RecordWildCards #-}
import Control.Monad
import Control.Monad.State.Strict
import qualified Data.List as List
import qualified Control.Monad.IO.Class as IOClass
type Node = Int
type Link = (Node,Node)
type Links = [Link]
type Gateway = Node
type Gateways = [Gateway]
data Game = Game { nbNodes :: Int, links :: Links, gateways :: Gateways }
computeNextTurn :: State Game Link
computeNextTurn = do
g <- get
inputLine <- IOClass.liftIO getLine -- this line causes problem
let node = read inputLine :: Int
let game#(Game _ ls gs) = g
let linkToSever = computeLinkToSever game node
let ls' = List.delete linkToSever ls
let game' = game{links = ls'}
put game'
return linkToSever
computeAllTurns :: State Game Links
computeAllTurns = do
linkToSever <- computeNextTurn
nextGames <- computeAllTurns
return (linkToSever : nextGames)
computeLinkToSever :: Game -> Node -> Link
computeLinkToSever _ _ = (0,1) -- just a dummy value
-- this function doesnt compute really anything for the moment
-- but it will depend on the value of node i got from IO
However I get an error at compilation:
No instance for (MonadIO Data.Functor.Identity.Identity)
arising from a use of liftIO
and I get the same style of error, if I try to use liftM and lift.
I have read some questions that are suggesting StateT and ST, which I don't grasp yet.
I am wondering if my current techique with a simple State is doomed to fail, and that indeed I can not use State, but StateT / ST ?
Or is there a possible operation to simply get the value from getLine, inside the State monad ?
As #bheklilr said in his comment, you can't use IO from State. The reason for that, basically, is that State (which is just shorthand for StateT over Identity) is no magic, so it's not going to be able to use anything more than
What you can already do in its base monad, Identity
The new operations provided by State itself
However, that first point also hints at the solution: if you change the base monad from Identity to some other monad m, then you get the capability to use the effects provided by m. In your case, by setting m to IO, you're good to go.
Note that if you have parts of your computation that don't need to do IO, but require access to your state, you can still express this fact by making their type something like
foo :: (Monad m) => Bar -> StateT Game m Baz
You can then compose foo with computations in StateT Game IO, but its type also makes it apparent that it can't possibly do any IO (or anything else base monad-specific).
You also mentioned ST in your question as possible solution. ST is not a monad transformer and thus doesn't allow you to import effects from some base monad.
just curious how to rewrite the following function to be called only once during program's lifetime ?
getHeader :: FilePath -> IO String
getHeader fn = readFile fn >>= return . take 13
Above function is called several times from various functions.
How to prevent reopening of the file if function gets called with the same parameter, ie. file name ?
I would encourage you to seek a more functional solution, for example by loading the headers you need up front and passing them around in some data structure like for example a Map. If explicitly passing it around is inconvenient, you can use a Reader or State monad transformer to handle that for you.
That said, you can accomplish this the way you wanted using by using unsafePerformIO to create a global mutable reference to hold your data structure.
import Control.Concurrent.MVar
import qualified Data.Map as Map
import System.IO.Unsafe (unsafePerformIO)
memo :: MVar (Map.Map FilePath String)
memo = unsafePerformIO (newMVar Map.empty)
{-# NOINLINE memo #-}
getHeader :: FilePath -> IO String
getHeader fn = modifyMVar memo $ \m -> do
case Map.lookup fn m of
Just header -> return (m, header)
Nothing -> do header <- take 13 `fmap` readFile fn
return (Map.insert fn header m, header)
I used an MVar here for thread safety. If you don't need that, you might be able to get away with using an IORef instead.
Also, note the NOINLINE pragma on memo to ensure that the reference is only created once. Without this, the compiler might inline it into getHeader, giving you a new reference each time.
The simplest thing is to just call it once at the beginning of main and pass the resulting String around to all the other functions that need it:
main = do
header <- getHeader
bigOldThingOne header
bigOldThingTwo header
You can use monad-memo package to wrap any monad into MemoT transformer. The memo table will be passed implicitly thoughout your monadic functions. Then use startEvalMemoT to convert memoized monad into ordinary IO:
{-# LANGUAGE NoMonomorphismRestriction #-}
import Control.Monad.Memo
getHeader :: FilePath -> IO String
getHeader fn = readFile fn >>= return . take 13
-- | 'memoized' version of getHeader
getHeaderm :: FilePath -> MemoT String String IO String
getHeaderm fn = memo (lift . getHeader) fn
-- | 'memoized' version of Prelude.print
printm a = memo (lift . print) a
-- | This will not print the last "Hello"
test = do
printm "Hello"
printm "World"
printm "Hello"
main :: IO ()
main = startEvalMemoT test
You should not use unsafePerformIO to solve this. The correct way to do exactly what you describe is to create an IORef that holds a Maybe, initially containing Nothing. Then you create an IO function which checks the value, and performs the computation if it is Nothing and stores the result as a Just. If it finds a Just it reuses the value.
All of this requires passing around the IORef reference, which is just as cumbersome as passing around the string itself, which is why everybody directly recommends just passing around the string itself, either explicitly or implicitly using the Reader monad.
There are incredibly few legitimate uses for unsafePerformIO and this is not one of them. Don't go down that path, otherwise you'll find yourself fighting Haskell when it keeps doing unexpected things. Every solution that uses unsafePerformIO as a "clever trick" always ends catastrophically (and that includes readFile).
Side note - you can simplify your getHeader function:
getHeader path = fmap (take 13) (readFile path)
Or
getHeader path = take 13 <$> readFile path