aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Oliver <contact@pauloliver.dev>2025-08-27 04:10:47 +0000
committerPaul Oliver <contact@pauloliver.dev>2025-08-27 04:17:18 +0000
commitec1a6fba4c944d95edb2397b47b6cebc59e2758d (patch)
tree48e4eccaa30f6607ceac01e1f97007b8d39f0f00
parent3806bd1f5ce56afdbb4cc0c1ed54d53e25603be2 (diff)
Moves commonly used `bracket` combinators into separate module
-rw-r--r--hsm-cam/Hsm/Cam.hs3
-rw-r--r--hsm-cam/hsm-cam.cabal2
-rw-r--r--hsm-core/Hsm/Core/Bracket.hs23
-rw-r--r--hsm-core/hsm-core.cabal8
-rw-r--r--hsm-gpio/Hsm/GPIO.hs12
5 files changed, 38 insertions, 10 deletions
diff --git a/hsm-cam/Hsm/Cam.hs b/hsm-cam/Hsm/Cam.hs
index c82cdd7..fe17057 100644
--- a/hsm-cam/Hsm/Cam.hs
+++ b/hsm-cam/Hsm/Cam.hs
@@ -44,6 +44,7 @@ import Hsm.Cam.FFI
, stopCamera
, stopCameraManager
)
+import Hsm.Core.Bracket (bracketConst, bracketLiftIO_)
import Hsm.Log (Log, Severity(Attention, Info, Trace), getLevel, logMsg, makeLoggerIO)
import MMAP (mapShared, mkMmapFlags, mmap, munmap, protRead)
import System.Directory (doesFileExist, removeFile)
@@ -127,8 +128,6 @@ runCam action = do
. bracketLiftIO_ createRequest (return ())
. bracket mapDmaBuffer unmapDmaBuffer $ \dmaBuffer -> evalStaticRep (Cam Rep {..}) action
where
- bracketConst alloc dealloc = bracket alloc dealloc . const
- bracketLiftIO_ alloc dealloc = bracket_ (liftIO alloc) (liftIO dealloc)
loggerAlloc = do
logMsg @"cam" Info "Registering FFI logger"
loggerIO <- makeLoggerIO @"cam"
diff --git a/hsm-cam/hsm-cam.cabal b/hsm-cam/hsm-cam.cabal
index 5c06ea7..fe767cb 100644
--- a/hsm-cam/hsm-cam.cabal
+++ b/hsm-cam/hsm-cam.cabal
@@ -13,6 +13,7 @@ library
, directory
, effectful-core
, effectful-plugin
+ , hsm-core
, hsm-log
, JuicyPixels
, monad-loops
@@ -44,6 +45,7 @@ executable test-cam
, directory
, effectful-core
, effectful-plugin
+ , hsm-core
, hsm-log
, JuicyPixels
, monad-loops
diff --git a/hsm-core/Hsm/Core/Bracket.hs b/hsm-core/Hsm/Core/Bracket.hs
new file mode 100644
index 0000000..f666d86
--- /dev/null
+++ b/hsm-core/Hsm/Core/Bracket.hs
@@ -0,0 +1,23 @@
+-- Resource management combinators for safe acquisition/release patterns.
+-- Provides specialized bracket variants for common scenarios.
+module Hsm.Core.Bracket
+ ( bracketConst
+ , bracketCont
+ , bracketLiftIO_
+ ) where
+
+import Control.Monad.Trans.Cont (Cont, cont)
+import Effectful (Eff, IOE, (:>), liftIO)
+import Effectful.Exception (bracket, bracket_)
+
+-- Ignores allocated resource in the action
+bracketConst :: Eff es a -> (a -> Eff es b) -> Eff es c -> Eff es c
+bracketConst alloc dealloc = bracket alloc dealloc . const
+
+-- Continuation-passing style integration
+bracketCont :: Eff es a -> (a -> Eff es b) -> Cont (Eff es c) a
+bracketCont alloc dealloc = cont $ bracket alloc dealloc
+
+-- Lifts IO operations into Effectful brackets
+bracketLiftIO_ :: IOE :> es => IO a -> IO b -> Eff es c -> Eff es c
+bracketLiftIO_ alloc dealloc = bracket_ (liftIO alloc) $ liftIO dealloc
diff --git a/hsm-core/hsm-core.cabal b/hsm-core/hsm-core.cabal
index 856a359..67a63e2 100644
--- a/hsm-core/hsm-core.cabal
+++ b/hsm-core/hsm-core.cabal
@@ -3,12 +3,16 @@ author: Paul Oliver <contact@pauloliver.dev>
name: hsm-core
version: 0.1.0.0
-
library
build-depends:
, base
+ , effectful-core
, template-haskell
+ , transformers
default-language: GHC2024
- exposed-modules: Hsm.Core.Serial
+ exposed-modules:
+ Hsm.Core.Bracket
+ Hsm.Core.Serial
+
ghc-options: -O2 -Wall -Werror -Wno-star-is-type -Wunused-packages
diff --git a/hsm-gpio/Hsm/GPIO.hs b/hsm-gpio/Hsm/GPIO.hs
index 0f320a1..8f3115d 100644
--- a/hsm-gpio/Hsm/GPIO.hs
+++ b/hsm-gpio/Hsm/GPIO.hs
@@ -11,7 +11,7 @@ module Hsm.GPIO
) where
import Control.Monad (forM_, void)
-import Control.Monad.Trans.Cont (cont, evalCont)
+import Control.Monad.Trans.Cont (evalCont)
import Data.Vector.Storable (fromList, replicate, unsafeWith)
import Effectful (Dispatch(Static), DispatchOf, Eff, IOE, (:>), liftIO)
import Effectful.Dispatch.Static (SideEffects(WithSideEffects), StaticRep, evalStaticRep, getStaticRep, unsafeEff_)
@@ -19,6 +19,7 @@ import Effectful.Exception (bracket)
import Foreign.C.String (withCString)
import Foreign.C.Types (CSize(CSize), CUInt)
import Foreign.Ptr (Ptr)
+import Hsm.Core.Bracket (bracketCont)
import Hsm.Core.Serial (makeSerial)
import Hsm.GPIO.FFI
( LineRequest
@@ -78,7 +79,6 @@ setAllPins lineValue = do
runGPIO :: (IOE :> es, Log "gpio" :> es) => String -> Eff (GPIO : es) a -> Eff es a
runGPIO consumer action = bracket lineRequestAlloc lineRequestDealloc $ \lineRequest -> evalStaticRep (GPIO lineRequest) action
where
- contBracket alloc dealloc = cont $ bracket alloc dealloc
chipPath = "/dev/gpiochip0"
chipAlloc = do
logMsg Info $ "Opening GPIO chip " <> chipPath
@@ -118,10 +118,10 @@ runGPIO consumer action = bracket lineRequestAlloc lineRequestDealloc $ \lineReq
lineRequestAlloc = do
logMsg Info "Allocating line request"
evalCont $ do
- chip <- contBracket chipAlloc chipDealloc
- lineSettings <- contBracket lineSettingsAlloc lineSettingsDealloc
- lineConfig <- contBracket (lineConfigAlloc lineSettings) lineConfigDealloc
- requestConfig <- contBracket requestConfigAlloc requestConfigDealloc
+ chip <- bracketCont chipAlloc chipDealloc
+ lineSettings <- bracketCont lineSettingsAlloc lineSettingsDealloc
+ lineConfig <- bracketCont (lineConfigAlloc lineSettings) lineConfigDealloc
+ requestConfig <- bracketCont requestConfigAlloc requestConfigDealloc
return . liftIO $ chipRequestLines chip requestConfig lineConfig
lineRequestDealloc lineRequest = do
logMsg Info "Releasing line request"