module System.Statgrab
(
Stats
, runStats
, async
, snapshot
, snapshots
, Stat
, Struct
, Host (..)
, CPU (..)
, CPUPercent (..)
, Memory (..)
, Load (..)
, User (..)
, Swap (..)
, FileSystem (..)
, DiskIO (..)
, NetworkIO (..)
, NetworkInterface (..)
, Page (..)
, Process (..)
, ProcessCount (..)
, HostState (..)
, CPUPercentSource (..)
, DeviceType (..)
, InterfaceMode (..)
, InterfaceStatus (..)
, ProcessState (..)
, ProcessSource (..)
, Async
, wait
) where
import Control.Applicative
import Control.Concurrent.Async (Async, wait)
import qualified Control.Concurrent.Async as Async
import qualified Control.Exception as E
import Control.Monad
import Control.Monad.IO.Class
import Control.Monad.Trans.Reader
import Data.IORef
import GHC.Word
import System.Statgrab.Base
import System.Statgrab.Internal
newtype Stats a = Stats { unwrap :: ReaderT (IORef Word) IO a }
deriving (Applicative, Functor, Monad, MonadIO)
runStats :: MonadIO m => Stats a -> m a
runStats = liftIO
. E.bracket (sg_init 0 >> sg_drop_privileges >> newIORef 1) destroy
. runReaderT
. unwrap
async :: Stats a -> Stats (Async a)
async (Stats s) = Stats $ do
ref <- ask
liftIO $ do
atomicModifyIORef' ref $ \ n -> (succ n, ())
Async.async $ runReaderT s ref `E.finally` destroy ref
snapshot :: (Stat (Struct a), Copy a) => Stats a
snapshot = liftIO (E.bracket acquireN releaseN copy)
snapshots :: (Stat (Struct a), Copy a) => Stats [a]
snapshots = liftIO (E.bracket acquireN releaseN copyBatch)
destroy :: IORef Word -> IO ()
destroy ref = do
n <- atomicModifyIORef' ref $ \n -> (pred n, n)
when (n == 1) $
void sg_shutdown