1{-# LANGUAGE DeriveDataTypeable #-}
2module Data.AutoUpdate where
5import Control.Concurrent (threadDelay, forkIO, ThreadId, killThread, myThreadId)
6import Control.Monad (join, forever)
7import Control.Exception (throwTo, Exception, handle, fromException, throwIO, assert)
8import Data.Typeable (Typeable)
10data UpdateSettings a = UpdateSettings
12 , updateSpawnThreshold :: !Int
13 , updateAction :: !(IO a)
16data Status a = AutoUpdated !a !Int !ThreadId | ManualUpdates !Int
17data AutoUpdate a = AutoUpdate
18 { auSettings :: !(UpdateSettings a)
19 , auStatus :: !(IORef (Status a))
22mkAutoUpdate :: UpdateSettings a -> IO (AutoUpdate a)
23mkAutoUpdate settings = do
24 istatus <- newIORef $ ManualUpdates 0
25 return $ AutoUpdate settings istatus
27data Action a = Return a | Manual | Spawn
29getCurrent :: AutoUpdate a -> IO a
30getCurrent (AutoUpdate (UpdateSettings freq spawnThreshold action) istatus) = do
31 ea <- atomicModifyIORef istatus $ \status ->
33 AutoUpdated a cnt tid -> (AutoUpdated a (succ cnt) tid, Return a)
34 ManualUpdates i -> (ManualUpdates (succ i), if i > spawnThreshold then Spawn else Manual)
41 join $ atomicModifyIORef istatus $ \status ->
43 AutoUpdated _ cnt old -> (AutoUpdated a cnt tid, throwTo old Replaced)
44 ManualUpdates cnt -> (AutoUpdated a cnt tid, return ())
47 spawn = handle onErr $ forever $ do
50 let stop = throwIO Replaced
51 join $ atomicModifyIORef istatus $ \status ->
54 | cnt >= 1 -> (AutoUpdated a 0 tid, return ())
55 | otherwise -> (ManualUpdates 0, stop)
56 ManualUpdates i -> assert False (ManualUpdates i, stop)
58 case fromException ex of
59 Just Replaced -> return ()
62 atomicModifyIORef istatus $ \status ->
64 AutoUpdated _ _ tid' | tid == tid' -> (ManualUpdates 0, ())
68data Replaced = Replaced
69 deriving (Show, Typeable)
70instance Exception Replaced
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list