@@ -4,16 +4,17 @@
44-- threads. These threads will automatically spawn and die based on the
55-- presence of a workload to process on.
66module Control.Reaper (
7− -- * Type
7+ -- * Settings
88 ReaperSettings
99 , defaultReaperSettings
10− , State(..)
1110 -- * Accessors
1211 , reaperAction
1312 , reaperDelay
1413 , reaperCons
1514 , reaperNull
1615 , reaperEmpty
16+ -- * Type
17+ , Reaper(..)
1718 -- * Creation
1819 , mkReaper
1920 -- * Helper
@@ -24,7 +25,7 @@ import Control.AutoUpdate.Util (atomicModifyIORef')
2425import Control.Concurrent (forkIO, threadDelay)
2526import Control.Exception (mask_)
2627import Control.Monad (join, void)
27−import Data.IORef (IORef, newIORef)
28+import Data.IORef (IORef, newIORef, readIORef)
2829
2930-- | Settings for creating a reaper. This type has two parameters:
3031-- @workload@ gives the entire workload, whereas @item@ gives an
@@ -86,6 +87,17 @@ defaultReaperSettings = ReaperSettings
8687 , reaperEmpty = []
8788 }
8889
90+-- | A data structure to hold reaper APIs.
91+data Reaper workload item = Reaper {
92+ -- | Adding an item to the workload
93+ reaperAdd :: item -> IO ()
94+ -- | Reading workload.
95+ , reaperRead :: IO workload
96+ -- | Stopping the reaper thread if exists.
97+ -- The current workload is returned.
98+ , reaperStop :: IO workload
99+ }
100+
89101-- | State of reaper.
90102data State workload = NoReaper -- ^ No reaper thread
91103 | Workload workload -- ^ The current jobs
@@ -95,11 +107,24 @@ data State workload = NoReaper -- ^ No reaper thread
95107-- for you automatically.
96108--
97109-- Since 0.1.1
98−mkReaper :: ReaperSettings workload item
99− -> IO (item -> IO (), IORef (State workload))
100−mkReaper settings = do
110+mkReaper :: ReaperSettings workload item -> IO (Reaper workload item)
111+mkReaper settings@ReaperSettings{..} = do
101112 stateRef <- newIORef NoReaper
102− return (update settings stateRef, stateRef)
113+ return Reaper {
114+ reaperAdd = update settings stateRef
115+ , reaperRead = readRef stateRef
116+ , reaperStop = stop stateRef
117+ }
118+ where
119+ readRef stateRef = do
120+ mx <- readIORef stateRef
121+ case mx of
122+ NoReaper -> return reaperEmpty
123+ Workload wl -> return wl
124+ stop stateRef = atomicModifyIORef' stateRef $ \mx ->
125+ case mx of
126+ NoReaper -> (NoReaper, reaperEmpty)
127+ Workload x -> (Workload reaperEmpty, x)
103128
104129update :: ReaperSettings workload item -> IORef (State workload) -> item
105130 -> IO ()