FunPtr callbacks broken?

Jeremy Shaw jeremy.shaw at linspireinc.com
Thu Oct 20 13:58:10 EDT 2005


Hello,

I am trying to use FunPtr for a callback from C, but I seem to be
getting the error:

simplejack: schedule: re-entered unsafely.
   Perhaps a 'foreign import unsafe' should be 'safe'?

Am I misusing something? Or is this a compiler bug? Google indicated
that the last time someone had this problem it was a compiler bug...

Here is the test program. It requires jack to be running
(http://jackit.sf.net) and I built it with:

ghc --make -fglasgow-exts SimpleJack.hs -o simplejack  -ljack

{{{

module Main where

import Foreign.C
import Foreign.Ptr
import Foreign.StablePtr
import Foreign.Storable
import Foreign.Marshal.Array
import Foreign.Marshal.Utils


data JackClient
data JackPort

-- typedef int  (*JackProcessCallback)(jack_nframes_t nframes, void *arg);
type JackProcessCallbackFunction = (CUInt -> StablePtr () -> IO CInt)
data JackProcessCallback = JackProcessCallback JackProcessCallbackFunction

foreign import ccall safe "wrapper" mkJackProcessCallback :: JackProcessCallbackFunction -> IO (FunPtr JackProcessCallbackFunction)
foreign import ccall safe "jack/jack.h jack_client_new" cjackClientNew :: CString -> IO (Ptr JackClient)
foreign import ccall safe "jack/jack.h jack_activate" jackActivate :: Ptr JackClient -> IO CInt
foreign import ccall safe "jack/jack.h jack_set_process_callback" cjackSetProcessCallback :: Ptr JackClient -> FunPtr JackProcessCallbackFunction -> StablePtr () -> IO ()


jackClientNew :: String -> IO (Ptr JackClient)
jackClientNew name =
    withCString name $ cjackClientNew

jackSetProcessCallback :: Ptr JackClient -> JackProcessCallbackFunction -> IO ()
jackSetProcessCallback client f =
    do cf <- mkJackProcessCallback f
       cjackSetProcessCallback client cf (castPtrToStablePtr nullPtr)

main =
    do client <- jackClientNew "Jack"
       if (client == nullPtr)
	  then error "jackClientNew Failed"
	  else putStrLn "jackClientNew succeeded."

       jackSetProcessCallback client simpleCallback
       ret <- jackActivate client
       if (ret /= 0)
	  then error "jackActivate failed."
	  else putStrLn "jackActivate succeeded."
       getLine
       loop


loop = loop

simpleCallback :: JackProcessCallbackFunction
simpleCallback nframes _ =
   do putStrLn ("callback: " ++ show nframes)
      return 0

}}}

Here is the sample output of a session -- note that things work ok if
the main program is blocking on getLine, but once it goes into the
loop, it fails immediately. If I expand the loop to do more stuff --
it seems to run longer but still eventually crashes.

{{{
jackClientNew succeeded.
jackActivate succeeded.
callback: 1024
callback: 1024
callback: 1024
callback: 1024
callback: 1024
callback: 1024
callback: 1024
callback: 1024
callback: 1024
callback: 1024
callback: 1024
callback: 1024
callback: 1024
<<I pressed enter here>>
simplejack: schedule: re-entered unsafely.
   Perhaps a 'foreign import unsafe' should be 'safe'?
}}}


Note: it crashes even if the callback is just:

simpleCallback nframes _ = return 0

Thanks!
Jeremy Shaw.



More information about the Glasgow-haskell-bugs mailing list