module Network.Protocol.Snmp.AgentX.Types ( SubAgentState(..) , Transaction(..) , runMIBTree , SubAgent , TransactionState(..) ) where import Control.Monad.State.Strict import Control.Monad.Reader import Network.Socket hiding (recv) import Control.Applicative import Data.IORef import GHC.Conc import Data.Map import Network.Protocol.Snmp.AgentX.Packet import Network.Protocol.Snmp.AgentX.MIBTree data Transaction = Transaction { tcontext :: Maybe Context , vblist :: [VarBind] , statusV :: TransactionState } deriving Show data TransactionState = TestSetT | CommitSetT | UndoSetT | CleanupSetT deriving (Show, Eq, Ord, Enum) data SubAgentState = SubAgentState { sysuptime :: IORef SysUptime , packetCounter :: IORef PacketID , mibs :: TVar Module , sock :: Socket , sessions :: IORef (Maybe SessionID) , transactions :: IORef (Map TransactionID Transaction) } type SubAgent = ReaderT SubAgentState IO -- | run MIBTree in SubAgent context, without lock, if trees was changed, retry runMIBTree :: MIBTree IO a -> SubAgent a runMIBTree f = do st <- mibs <$> ask oldst <- liftIO $ readTVarIO st (a, newst) <- liftIO $ runStateT f oldst result <- lift . atomically $ do oldst' <- readTVar st if oldst' == newst then writeTVar st newst >> return True else return False if result then return a else runMIBTree f