git-annex/Utility/TList.hs
Joey Hess e213ef310f git-annex (5.20140717) unstable; urgency=high
* Fix minor FD leak in journal code. Closes: #754608
  * direct: Fix handling of case where a work tree subdirectory cannot
    be written to due to permissions.
  * migrate: Avoid re-checksumming when migrating from hashE to hash backend.
  * uninit: Avoid failing final removal in some direct mode repositories
    due to file modes.
  * S3: Deal with AWS ACL configurations that do not allow creating or
    checking the location of a bucket, but only reading and writing content to
    it.
  * resolvemerge: New plumbing command that runs the automatic merge conflict
    resolver.
  * Deal with change in git 2.0 that made indirect mode merge conflict
    resolution leave behind old files.
  * sync: Fix git sync with local git remotes even when they don't have an
    annex.uuid set. (The assistant already did so.)
  * Set gcrypt-publish-participants when setting up a gcrypt repository,
    to avoid unncessary passphrase prompts.
    This is a security/usability tradeoff. To avoid exposing the gpg key
    ids who can decrypt the repository, users can unset
    gcrypt-publish-participants.
  * Install nautilus hooks even when ~/.local/share/nautilus/ does not yet
    exist, since it is not automatically created for Gnome 3 users.
  * Windows: Move .vbs files out of git\bin, to avoid that being in the
    PATH, which caused some weird breakage. (Thanks, divB)
  * Windows: Fix locking issue that prevented the webapp starting
    (since 5.20140707).

# imported from the archive
2014-07-17 11:27:25 -04:00

69 lines
2 KiB
Haskell

{- Transactional lists
-
- Based on DLists, a transactional list can quickly and efficiently
- have items inserted at either end, or a whole list appended to it.
-
- Unlike a TQueue, the entire contents of a TList can be efficiently
- read without modifying it.
-
- Copyright 2013 Joey Hess <joey@kitenet.net>
-}
{-# LANGUAGE BangPatterns #-}
module Utility.TList where
import Common
import Control.Concurrent.STM
import qualified Data.DList as D
type TList a = TMVar (D.DList a)
newTList :: STM (TList a)
newTList = newEmptyTMVar
{- Gets the contents of the TList. Blocks when empty.
- TList is left empty. -}
getTList :: TList a -> STM [a]
getTList tlist = D.toList <$> getTDList tlist
getTDList :: TList a -> STM (D.DList a)
getTDList = takeTMVar
{- Replaces the contents of the TList. -}
setTList :: TList a -> [a] -> STM ()
setTList tlist = setTDList tlist . D.fromList
setTDList :: TList a -> D.DList a -> STM ()
setTDList tlist = modifyTList tlist . const
{- Takes anything currently in the TList, without blocking.
- TList is left empty. -}
takeTList :: TList a -> STM [a]
takeTList tlist = maybe [] D.toList <$> tryTakeTMVar tlist
{- Reads anything in the list, without modifying it, or blocking. -}
readTList :: TList a -> STM [a]
readTList tlist = maybe [] D.toList <$> tryReadTMVar tlist
{- Mutates a TList. -}
modifyTList :: TList a -> (D.DList a -> D.DList a) -> STM ()
modifyTList tlist a = do
dl <- fromMaybe D.empty <$> tryTakeTMVar tlist
let !dl' = a dl
{- The TMVar is left empty when the list is empty.
- Thus attempts to read it automatically block. -}
unless (emptyDList dl') $
putTMVar tlist dl'
where
emptyDList = D.list True (\_ _ -> False)
consTList :: TList a -> a -> STM ()
consTList tlist v = modifyTList tlist $ \dl -> D.cons v dl
snocTList :: TList a -> a -> STM ()
snocTList tlist v = modifyTList tlist $ \dl -> D.snoc dl v
appendTList :: TList a -> [a] -> STM ()
appendTList tlist l = modifyTList tlist $ \dl -> D.append dl (D.fromList l)