@@ -110,19 +110,26 @@ spawn settings stateRef = void . forkIO $ loop settings stateRef
110110loop :: ReaperSettings workload item -> IORef (Maybe workload) -> IO ()
111111loop settings@ReaperSettings{..} stateRef = do
112112 threadDelay reaperDelay
113− wl1 <- atomicModifyIORef' stateRef get
114− wl2 <- reaperAction wl1
115− join $ atomicModifyIORef' stateRef (check wl2)
113+ -- Getting the current jobs. Push an empty job to the reference.
114+ wl <- atomicModifyIORef' stateRef swapWithEmpty
115+ -- Do the jobs. A function to merge the left jobs and
116+ -- new jobs is returned.
117+ merge <- reaperAction wl
118+ -- Merging the left jobs and new jobs.
119+ -- If there is no jobs, this thread finishes.
120+ join $ atomicModifyIORef' stateRef (check merge)
116121 where
117− get Nothing = error "Control.Reaper.loop: unexpected Nothing (1)"
118− get (Just wl) = (Just reaperEmpty, wl)
122+ swapWithEmpty Nothing = error "Control.Reaper.loop: unexpected Nothing (1)"
123+ swapWithEmpty (Just wl) = (Just reaperEmpty, wl)
119124
120125 check _ Nothing = error "Control.Reaper.loop: unexpected Nothing (2)"
121− check wl2 (Just wl3)
122− | reaperNull wl4 = (Nothing, return ())
123− | otherwise = (Just wl4, loop settings stateRef)
126+ check merge (Just wl)
127+ -- If there is no workload, reaper is terminated.
128+ | reaperNull wl' = (Nothing, return ())
129+ -- If there are workloads, carry it out.
130+ | otherwise = (Just wl', loop settings stateRef)
124131 where
125− wl4 = wl2 wl3
132+ wl' = merge wl
126133
127134-- | A helper function for creating 'reaperAction' functions. You would
128135-- provide this function with a function to process a single work item and