module MTP.Handle (MTPHandle, isClosed, open, close, withMTPHandle) where
import MTP.Foreign (MTPDevice)
import Control.Concurrent.MVar
import Control.Monad
import Foreign
data HandleState = Closed | Open deriving Eq
data MTPHandle_ = MTPHandle_
{ haDev :: !(ForeignPtr MTPDevice)
, haState :: HandleState
}
data MTPHandle = MTPHandle (MVar MTPHandle_)
open :: Ptr MTPDevice -> IO MTPHandle
open dptr = do
dev <- newForeignPtr_ dptr
h_ <- newMVar $ MTPHandle_ dev Open
return (MTPHandle h_)
close :: MTPHandle -> IO ()
close (MTPHandle hv) = modifyMVar_ hv (\x -> return x { haState = Closed })
isClosed :: MTPHandle -> IO Bool
isClosed (MTPHandle hv) = withMVar hv (\x -> return $ haState x == Closed)
withMTPHandle :: MTPHandle -> (Ptr MTPDevice -> IO a) -> IO a
withMTPHandle h@(MTPHandle hv) f = do
closed <- isClosed h
when closed (fail "MTPHandle is closed")
withMVar hv (\x -> withForeignPtr (haDev x) f)