mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-05-19 03:20:21 -07:00
Fix historyHook memory leak
updateHistory leaks unfiltered windows from previous states as it is never forced. The consumer of such data structure is not visible to ghc, so the demand analysis has to fallback on pure laziness. We fix this inserting evaluation points on the `historyHook` function. We do this for two reasons, this is the only function calling `updateHistory`. Plus we cannot do it clearly at the `updateHistory` function as we operate inside a continuation on withWindowSet. In respect to the `put`, everything would be a big thunk.
This commit is contained in:
parent
282afefddf
commit
ed5d6f0d78
@ -34,6 +34,7 @@ module XMonad.Actions.GroupNavigation ( -- * Usage
|
|||||||
|
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import Control.Monad.State
|
import Control.Monad.State
|
||||||
|
import Control.Seq (using, seqFoldable, rseq)
|
||||||
import Data.Map ((!))
|
import Data.Map ((!))
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import Data.Sequence (Seq, ViewL (EmptyL, (:<)), viewl, (<|), (><), (|>))
|
import Data.Sequence (Seq, ViewL (EmptyL, (:<)), viewl, (<|), (><), (|>))
|
||||||
@ -166,15 +167,20 @@ instance ExtensionClass HistoryDB where
|
|||||||
-- | Action that needs to be executed as a logHook to maintain the
|
-- | Action that needs to be executed as a logHook to maintain the
|
||||||
-- focus history of all windows as the WindowSet changes.
|
-- focus history of all windows as the WindowSet changes.
|
||||||
historyHook :: X ()
|
historyHook :: X ()
|
||||||
historyHook = XS.get >>= updateHistory >>= XS.put
|
historyHook = do
|
||||||
|
db <- XS.get
|
||||||
|
db'@(HistoryDB cur del) <- updateHistory db
|
||||||
|
let del' = del `using` seqFoldable rseq
|
||||||
|
cur' = cur `using` seqFoldable rseq
|
||||||
|
cur' `seq` del' `seq` XS.put db'
|
||||||
|
|
||||||
-- Updates the history in response to a WindowSet change
|
-- Updates the history in response to a WindowSet change
|
||||||
updateHistory :: HistoryDB -> X HistoryDB
|
updateHistory :: HistoryDB -> X HistoryDB
|
||||||
updateHistory (HistoryDB oldcur oldhist) = withWindowSet $ \ss -> do
|
updateHistory (HistoryDB oldcur oldhist) = withWindowSet $ \ss ->
|
||||||
let newcur = SS.peek ss
|
let newcur = SS.peek ss
|
||||||
wins = Set.fromList $ SS.allWindows ss
|
wins = Set.fromList $ SS.allWindows ss
|
||||||
newhist = Seq.filter (`Set.member` wins) (ins oldcur oldhist)
|
newhist = Seq.filter (`Set.member` wins) (ins oldcur oldhist)
|
||||||
return $ HistoryDB newcur (del newcur newhist)
|
in pure $ HistoryDB newcur (del newcur newhist)
|
||||||
where
|
where
|
||||||
ins x xs = maybe xs (<| xs) x
|
ins x xs = maybe xs (<| xs) x
|
||||||
del x xs = maybe xs (\x' -> Seq.filter (/= x') xs) x
|
del x xs = maybe xs (\x' -> Seq.filter (/= x') xs) x
|
||||||
|
@ -61,7 +61,8 @@ library
|
|||||||
unix,
|
unix,
|
||||||
X11 >= 1.10 && < 1.11,
|
X11 >= 1.10 && < 1.11,
|
||||||
xmonad >= 0.16.99999 && < 0.18,
|
xmonad >= 0.16.99999 && < 0.18,
|
||||||
utf8-string
|
utf8-string,
|
||||||
|
parallel
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
|
|
||||||
cpp-options: -DXMONAD_CONTRIB_VERSION_MAJOR=0
|
cpp-options: -DXMONAD_CONTRIB_VERSION_MAJOR=0
|
||||||
@ -448,6 +449,7 @@ test-suite tests
|
|||||||
, process
|
, process
|
||||||
, unix
|
, unix
|
||||||
, utf8-string
|
, utf8-string
|
||||||
|
, parallel
|
||||||
, xmonad >= 0.16.9999 && < 0.18
|
, xmonad >= 0.16.9999 && < 0.18
|
||||||
cpp-options: -DTESTING
|
cpp-options: -DTESTING
|
||||||
ghc-options: -Wall -Wno-unused-do-bind
|
ghc-options: -Wall -Wno-unused-do-bind
|
||||||
|
Loading…
x
Reference in New Issue
Block a user