diff options
Diffstat (limited to 'Presence')
-rw-r--r-- | Presence/main.hs | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/Presence/main.hs b/Presence/main.hs index f77e582b..4168feca 100644 --- a/Presence/main.hs +++ b/Presence/main.hs | |||
@@ -119,27 +119,32 @@ sendPresence chan jid status = | |||
119 | 119 | ||
120 | lookupT jid subscribers = MaybeT . return $ Map.lookup jid subscribers | 120 | lookupT jid subscribers = MaybeT . return $ Map.lookup jid subscribers |
121 | 121 | ||
122 | update_presence subscribers state getStatus = | 122 | update_presence greedy subscribers state getStatus = |
123 | forM_ (Set.toList state) $ \jid -> do | 123 | forM_ (Set.toList state) $ \jid -> do |
124 | let status = getStatus jid | 124 | let status = getStatus jid |
125 | runMaybeT $ do | 125 | runMaybeT $ do |
126 | chan <- lookupT jid subscribers | 126 | chan <- lookupT jid subscribers |
127 | sendPresence chan jid status | 127 | sendPresence chan jid status |
128 | runMaybeT $ do | ||
129 | chan <- MaybeT . return $ greedy | ||
130 | sendPresence chan jid status | ||
128 | putStrLn $ bshow jid <++> " " <++> bshow status | 131 | putStrLn $ bshow jid <++> " " <++> bshow status |
129 | 132 | ||
130 | type RefCount = Int | 133 | type RefCount = Int |
131 | 134 | ||
132 | data PresenceState = PresenceState { | 135 | data PresenceState = PresenceState |
133 | currentTTY :: TVar ByteString, | 136 | { currentTTY :: TVar ByteString |
134 | activeUsers :: TVar (Set JID), | 137 | , activeUsers :: TVar (Set JID) |
135 | subscriberMap :: TVar (Map JID (RefCount,TChan Presence)) | 138 | , subscriberMap :: TVar (Map JID (RefCount,TChan Presence)) |
139 | , greedySubscriber :: TMVar (RefCount,TChan Presence) | ||
136 | } | 140 | } |
137 | 141 | ||
138 | newPresenceState = atomically $ do | 142 | newPresenceState = atomically $ do |
139 | tty <- newTVar "" | 143 | tty <- newTVar "" |
140 | us <- newTVar (Set.empty) | 144 | us <- newTVar (Set.empty) |
141 | subs <- newTVar (Map.empty) | 145 | subs <- newTVar (Map.empty) |
142 | return $ PresenceState tty us subs | 146 | greedy <- newEmptyTMVar |
147 | return $ PresenceState tty us subs greedy | ||
143 | 148 | ||
144 | track_login state e = do | 149 | track_login state e = do |
145 | #ifndef NOUTMP | 150 | #ifndef NOUTMP |
@@ -152,25 +157,27 @@ track_login state e = do | |||
152 | then Just (jid user host tty) | 157 | then Just (jid user host tty) |
153 | else Nothing | 158 | else Nothing |
154 | new_users = Set.fromList $ mapMaybe (toJabberId "localhost") us | 159 | new_users = Set.fromList $ mapMaybe (toJabberId "localhost") us |
155 | (tty,known_users,subs) <- atomically $ do | 160 | (tty,known_users,subs,greedy) <- atomically $ do |
156 | tty <- readTVar $ currentTTY state | 161 | tty <- readTVar $ currentTTY state |
157 | st <- flip swapTVar new_users $ activeUsers state | 162 | st <- flip swapTVar new_users $ activeUsers state |
158 | xs <- readTVar $ subscriberMap state | 163 | xs <- readTVar $ subscriberMap state |
159 | return (tty,st,fmap snd xs) | 164 | greedy <- tryReadTMVar $ greedySubscriber state |
165 | return (tty,st,fmap snd xs,fmap snd greedy) | ||
160 | let arrivals = new_users \\ known_users | 166 | let arrivals = new_users \\ known_users |
161 | departures = known_users \\ new_users | 167 | departures = known_users \\ new_users |
162 | update_presence subs departures $ const Offline | 168 | update_presence greedy subs departures $ const Offline |
163 | update_presence subs arrivals $ matchResource tty | 169 | update_presence greedy subs arrivals $ matchResource tty |
164 | 170 | ||
165 | on_chvt state vtnum = do | 171 | on_chvt state vtnum = do |
166 | let tty = L.snoc "tty" $ intToDigit (fromIntegral vtnum) | 172 | let tty = L.snoc "tty" $ intToDigit (fromIntegral vtnum) |
167 | L.putStrLn $ "VT switch: " <++> tty | 173 | L.putStrLn $ "VT switch: " <++> tty |
168 | (users,subs) <- atomically $ do | 174 | (users,subs,greedy) <- atomically $ do |
169 | us <- readTVar $ activeUsers state | 175 | us <- readTVar $ activeUsers state |
170 | subs <- readTVar $ subscriberMap state | 176 | subs <- readTVar $ subscriberMap state |
171 | writeTVar (currentTTY state) tty | 177 | writeTVar (currentTTY state) tty |
172 | return (us,fmap snd subs) | 178 | greedy <- tryReadTMVar $ greedySubscriber state |
173 | update_presence subs users $ matchResource tty | 179 | return (us,fmap snd subs,fmap snd greedy) |
180 | update_presence greedy subs users $ matchResource tty | ||
174 | 181 | ||
175 | 182 | ||
176 | start :: IO () | 183 | start :: IO () |