Andreas Klebinger pushed to branch wip/andreask/hadrian_race at Glasgow Haskell Compiler / GHC

Commits:

2 changed files:

Changes:

  • libraries/ghc-boot/GHC/Unit/Database.hs
    ... ... @@ -317,17 +317,29 @@ data DbInstUnitId
    317 317
     -- | Represents a lock of a package db.
    
    318 318
     newtype PackageDbLock = PackageDbLock Handle
    
    319 319
     
    
    320
    --- | Run the action under a lock, then return the result.
    
    321
    --- If the mode is R/W the *caller* needs to either free the lock or pass it
    
    322
    --- on to code that will.
    
    320
    +-- | Take a lock on the package database and then run the action.
    
    323 321
     --
    
    324
    --- If an exception is raised the lock is released.
    
    322
    +--   - In read-only mode, this takes and releases a shared lock.
    
    323
    +--   - In read-write mode, this takes an exclusive lock, and the caller
    
    324
    +--     must arrange for this lock to be released:
    
    325
    +--
    
    326
    +--        - either the inner action releases it, or
    
    327
    +--        - the inner action returns the lock and the caller
    
    328
    +--          of 'withLockedPackageDb' is responsible for releasing it.
    
    329
    +--
    
    330
    +-- If an exception escapes the inner action, the lock is released.
    
    331
    +--
    
    332
    +-- See Note [ghc-pkg database locking] in ghc-pkg/Main.hs
    
    325 333
     withLockedPackageDb :: DbOpenMode m t -> FilePath -> (PackageDbLock -> IO a) -> IO a
    
    326
    -withLockedPackageDb mode file act = do
    
    327
    -   lock <- lockPackageDbWith (lock_mode mode) file
    
    328
    -   r <- act lock `onException` unlockPackageDb lock
    
    329
    -   when (isDbOpenReadMode mode ) $ unlockPackageDb lock
    
    330
    -   pure r
    
    334
    +withLockedPackageDb mode file =
    
    335
    +  bracket_for_mode
    
    336
    +    (lockPackageDbWith (lock_mode mode) file)
    
    337
    +    unlockPackageDb
    
    338
    +  where
    
    339
    +    bracket_for_mode = 
    
    340
    +      case mode of
    
    341
    +        DbOpenReadOnly  -> bracket
    
    342
    +        DbOpenReadWrite -> bracketOnError
    
    331 343
       where
    
    332 344
        lock_mode :: DbOpenMode m t -> LockMode
    
    333 345
        lock_mode DbOpenReadOnly = SharedLock
    
    ... ... @@ -529,8 +541,8 @@ headerMagic = BS.Char8.pack "\0ghcpkg\0"
    529 541
     
    
    530 542
     -- | Feed a 'Get' decoder with data chunks from a file.
    
    531 543
     --
    
    532
    --- The file is already locked when we call this. We only need to pass it on
    
    533
    --- if we are in R/W mode.
    
    544
    +-- Requires a lock (either shared or exclusive) on the package database,
    
    545
    +-- which it returns unchanged.
    
    534 546
     decodeFromFile :: FilePath -> DbOpenMode mode PackageDbLock -> Get pkgs ->
    
    535 547
                       IO (pkgs, DbOpenMode mode PackageDbLock)
    
    536 548
     decodeFromFile file mode decoder = case mode of
    

  • utils/ghc-pkg/Main.hs
    ... ... @@ -875,31 +875,30 @@ lookForPackageDBIn dir = do
    875 875
     
    
    876 876
     {- Note [ghc-pkg database locking]
    
    877 877
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    878
    -It's important for ghc-pkg, GHC and hadrian to always see a consistent state for
    
    879
    -package databases. To ensure this we generally tacke a lock both for reading and
    
    880
    -writing to the package database.
    
    881
    -
    
    882
    -The general idea is we use `withLockedPackageDb` to lock an already existing
    
    883
    -database in both modes. Which behaves differently for reads and modify.
    
    884
    -
    
    885
    -In read mode we take a shared lock before we start reading, run the argument to
    
    886
    -withLockedPackageDb and simply unlock the DB after. We need to lock it to avoid
    
    887
    -concurrent invocations from deleting files from the db before we managed to read
    
    888
    -them. This occasionally happened in #22870. Not that historically we only used
    
    889
    -to lock the package db during reads on windows, for reasons that seem to have been
    
    890
    -bogus given the existence of #22870. And it was partially discussed in #16773.
    
    891
    -
    
    892
    -When modifying a package database we also use withLockedPackageDb but we take
    
    893
    -an *exclusive* lock and most importantly we don't unlock the DB after the action
    
    894
    -has run unless an exception occurs.
    
    895
    -Instead the action we are must ensure the lock is either freed, or returned
    
    896
    -as part of the result to be freed later by the caller of withLockedPackageDB.
    
    897
    -Typically by storing it inside either a `DbOpenMode` or `PackageDB`.
    
    898
    -
    
    899
    -While this setup is a bit cumbersome it seemed to be the easiest way to ensure
    
    878
    +It's important for ghc-pkg, GHC and Hadrian to always see a consistent state for
    
    879
    +package databases. To ensure this, we always take a lock before reading or writing
    
    880
    +to a package database.
    
    881
    +
    
    882
    +The general idea is we use 'withLockedPackageDb' to lock an already existing
    
    883
    +database in both modes:
    
    884
    +
    
    885
    +  - In read-only mode, we take a *shared* lock before reading and unlock afterwards.
    
    886
    +    Locking is needed to avoid a concurrent invocation of ghc-pkg deleting files from
    
    887
    +    the db before we manage to read them. This occasionally happened in #22870.
    
    888
    +    (Note that, historically, we used to only lock the package db during reads on
    
    889
    +     Windows, but the justification seemed insufficient given #22870. See also #16773.)
    
    890
    +
    
    891
    +  - In read-write mode, we take an **exclusive** lock on the package database.
    
    892
    +    However, we don't automatically release the lock after the inner action completes
    
    893
    +    (unless an exception occurs). Instead, either the inner action itself releases the
    
    894
    +    lock, or it returns it, in which case it is the caller of 'withLockedPackageDb'
    
    895
    +    that is responsible for releasing the lock. Typically, the exclusive lock is stored
    
    896
    +    in 'PackageDB', with the type informing us that we have a lock we are responsible for
    
    897
    +    releasing. 'updateDBCache' eventually releases it.
    
    898
    +
    
    899
    +While this setup is a bit cumbersome, it seemed to be the easiest way to ensure
    
    900 900
     that locks are consistently held over reads/modifications of a database without
    
    901 901
     engaging in a larger refactor of the ghc-pkg code.
    
    902
    -
    
    903 902
     -}
    
    904 903
     readParseDatabase :: forall mode t. Verbosity
    
    905 904
                       -> Maybe (FilePath,Bool)
    
    ... ... @@ -923,7 +922,7 @@ readParseDatabase verbosity mb_user_conf mode use_cache path
    923 922
              -- Take a lock to use while we read the DB
    
    924 923
              Right fs -> withLockedPackageDb mode cache $ \lock -> do
    
    925 924
               if not use_cache
    
    926
    -            then ignore_cache (lock) (const $ return ())
    
    925
    +            then ignore_cache lock (const $ return ())
    
    927 926
                 else do
    
    928 927
                       e_tcache <- tryIO $ getModificationTime cache
    
    929 928
                       case e_tcache of