13import qualified Data.IORef as I
14import Control.Concurrent (forkIO, threadDelay, myThreadId, killThread)
15import Control.Monad (forever)
16import qualified Control.Exception as E
18-- FIXME implement stopManager
21newtype Manager = Manager (I.IORef [Handle])
22data Handle = Handle (IO ()) (I.IORef State)
23data State = Active | Inactive | Paused | Canceled
25initialize :: Int -> IO Manager
26initialize timeout = do
28 _ <- forkIO $ forever $ do
30 ms <- I.atomicModifyIORef ref (\x -> ([], x))
32 I.atomicModifyIORef ref (\x -> (ms' x, ()))
35 go [] front = return front
36 go (m@(Handle onTimeout iactive):rest) front = do
37 state <- I.atomicModifyIORef iactive (\x -> (go' x, x))
40 onTimeout `E.catch` ignoreAll
42 Canceled -> go rest front
43 _ -> go rest (front . (:) m)
47ignoreAll :: E.SomeException -> IO ()
48ignoreAll _ = return ()
50register :: Manager -> IO () -> IO Handle
51register (Manager ref) onTimeout = do
52 iactive <- I.newIORef Active
53 let h = Handle onTimeout iactive
54 I.atomicModifyIORef ref (\x -> (h : x, ()))
57registerKillThread :: Manager -> IO Handle
58registerKillThread m = do
60 register m $ killThread tid
62tickle, pause, resume, cancel :: Handle -> IO ()
63tickle (Handle _ iactive) = I.writeIORef iactive Active
64pause (Handle _ iactive) = I.writeIORef iactive Paused
66cancel (Handle _ iactive) = I.writeIORef iactive Canceled
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