Pathfinder 0.5.8 → 0.5.9
raw patch · 3 files changed
+33/−18 lines, 3 filessetup-changedPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- Pathfinder.cabal +1/−1
- Setup.hs +1/−1
- src/Database/Pathfinder.hsc +31/−16
Pathfinder.cabal view
@@ -1,5 +1,5 @@ Name: Pathfinder-Version: 0.5.8+Version: 0.5.9 Synopsis: Relational optimiser and code generator Description: The library provides FFI bindings to the Pathfinder relational optimiser and
Setup.hs view
@@ -63,7 +63,7 @@ let script = [ "rm -r -f pathfinder" , "tar xzf pathfinder.tar.gz" , "cd pathfinder"- , "export CFLAGS=' " ++ cflags ++ " -fno-jump-tables '"+ , "export CFLAGS=' " ++ cflags ++ " -fno-jump-tables -fPIC '" , "sh configure --prefix=`pwd` --enable-static --disable-shared" , "make" , "make install"
src/Database/Pathfinder.hsc view
@@ -13,10 +13,22 @@ import Foreign import Foreign.C +import Control.Concurrent.MVar (MVar,takeMVar,putMVar,newEmptyMVar)+import qualified System.IO.Unsafe+ import qualified Data.Text as T import qualified Data.Text.Encoding as T import qualified Data.ByteString as B +-- | This is a global synchronisation variable used to guard calls to the+-- Pathfinder C library. The C library appears not to be thread safe and this+-- variable is used to make sure that only one pathfinder call is made at time+-- even in the presence of parallel or concurrent program execution.+{-# NOINLINE globalMVar #-}+globalMVar :: MVar ()+globalMVar = System.IO.Unsafe.unsafePerformIO (newEmptyMVar)++ #include <pathfinder.h> newtype COutputFormat = COutputFormat { unCOutputFormat :: CInt }@@ -54,21 +66,24 @@ -> OutputFormat -- ^ Output format -> IO (Either ErrorString OutputString) pathfinder xml optimisation output = do- let bs = T.encodeUtf8 (T.pack xml)- B.useAsCString bs $ \c_xml -> - alloca $ \c_ptr ->- alloca $ \c_err -> do- c_opt <- case optimisation of- [] -> return nullPtr- _ -> newCString optimisation+ putMVar globalMVar ()+ let bs = T.encodeUtf8 (T.pack xml)+ r <- B.useAsCString bs $ \c_xml -> + alloca $ \c_ptr ->+ alloca $ \c_err -> do+ c_opt <- case optimisation of+ [] -> return nullPtr+ _ -> newCString optimisation - ci <- c_PFcompile_ferry_opt c_ptr c_err c_xml (outputFormatToCInt output) c_opt- free c_opt+ ci <- c_PFcompile_ferry_opt c_ptr c_err c_xml (outputFormatToCInt output) c_opt+ free c_opt - if ci == 0- then do- c_string <- peek c_ptr- r <- fmap (T.unpack . T.decodeUtf8) (B.packCString c_string)- free c_string- return (Right r)- else fmap (Left . T.unpack . T.decodeUtf8) (B.packCString c_err)+ if ci == 0+ then do+ c_string <- peek c_ptr+ r <- fmap (T.unpack . T.decodeUtf8) (B.packCString c_string)+ free c_string+ return (Right r)+ else fmap (Left . T.unpack . T.decodeUtf8) (B.packCString c_err)+ takeMVar globalMVar+ return r