[commit: packages/Cabal] ghc-head: A fix for my previous fix for 'getSourceFiles'. (81d07bf)

git at git.haskell.org git at git.haskell.org
Mon Aug 26 23:22:59 CEST 2013


Repository : ssh://git@git.haskell.org/Cabal

On branch  : ghc-head
Link       : http://git.haskell.org/?p=packages/Cabal.git;a=commit;h=81d07bf23e6669bacc9745f70b23cb17a330059f

>---------------------------------------------------------------

commit 81d07bf23e6669bacc9745f70b23cb17a330059f
Author: Mikhail Glushenkov <the.dead.shall.rise at gmail.com>
Date:   Mon Apr 29 22:21:23 2013 +0200

    A fix for my previous fix for 'getSourceFiles'.
    
    Apparently, lazy I/O was involved after all. 'openFile' instead of 'withFile'
    was deliberate - see the use of 'unsafeInterleaveIO' in
    'packageIndexFromCache'. Fixed by adding a strict version of 'getSourceFiles'.


>---------------------------------------------------------------

81d07bf23e6669bacc9745f70b23cb17a330059f
 cabal-install/Distribution/Client/IndexUtils.hs    |   51 +++++++++++++++-----
 cabal-install/Distribution/Client/Sandbox/Index.hs |    5 +-
 2 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/cabal-install/Distribution/Client/IndexUtils.hs b/cabal-install/Distribution/Client/IndexUtils.hs
index 680e985..4b81ae5 100644
--- a/cabal-install/Distribution/Client/IndexUtils.hs
+++ b/cabal-install/Distribution/Client/IndexUtils.hs
@@ -13,6 +13,7 @@
 module Distribution.Client.IndexUtils (
   getInstalledPackages,
   getSourcePackages,
+  getSourcePackagesStrict,
   convert,
 
   readPackageIndexFile,
@@ -130,16 +131,29 @@ convert index' = PackageIndex.fromList
 -- This is a higher level wrapper used internally in cabal-install.
 --
 getSourcePackages :: Verbosity -> [Repo] -> IO SourcePackageDb
-getSourcePackages verbosity [] = do
+getSourcePackages verbosity repos = getSourcePackages' verbosity repos
+                                    ReadPackageIndexLazyIO
+
+-- | Like 'getSourcePackages', but reads the package index strictly. Useful if
+-- you want to write to the package index after having read it.
+getSourcePackagesStrict :: Verbosity -> [Repo] -> IO SourcePackageDb
+getSourcePackagesStrict verbosity repos = getSourcePackages' verbosity repos
+                                          ReadPackageIndexStrict
+
+-- | Common implementation used by getSourcePackages and
+-- getSourcePackagesStrict.
+getSourcePackages' :: Verbosity -> [Repo] -> ReadPackageIndexMode
+                      -> IO SourcePackageDb
+getSourcePackages' verbosity [] _mode = do
   warn verbosity $ "No remote package servers have been specified. Usually "
                 ++ "you would have one specified in the config file."
   return SourcePackageDb {
     packageIndex       = mempty,
     packagePreferences = mempty
   }
-getSourcePackages verbosity repos = do
+getSourcePackages' verbosity repos mode = do
   info verbosity "Reading available packages..."
-  pkgss <- mapM (readRepoIndex verbosity) repos
+  pkgss <- mapM (\r -> readRepoIndex verbosity r mode) repos
   let (pkgs, prefs) = mconcat pkgss
       prefs' = Map.fromListWith intersectVersionRanges
                  [ (name, range) | Dependency name range <- prefs ]
@@ -157,9 +171,9 @@ getSourcePackages verbosity repos = do
 --
 -- This is a higher level wrapper used internally in cabal-install.
 --
-readRepoIndex :: Verbosity -> Repo
+readRepoIndex :: Verbosity -> Repo -> ReadPackageIndexMode
               -> IO (PackageIndex SourcePackage, [Dependency])
-readRepoIndex verbosity repo =
+readRepoIndex verbosity repo mode =
   let indexFile = repoLocalDir repo </> "00-index.tar"
       cacheFile = repoLocalDir repo </> "00-index.cache"
   in handleNotFound $ do
@@ -167,7 +181,7 @@ readRepoIndex verbosity repo =
     whenCacheOutOfDate indexFile cacheFile $ do
       info verbosity "Updating the index cache file..."
       updatePackageIndexCacheFile indexFile cacheFile
-    readPackageIndexCacheFile mkAvailablePackage indexFile cacheFile
+    readPackageIndexCacheFile mkAvailablePackage indexFile cacheFile mode
 
   where
     mkAvailablePackage pkgEntry =
@@ -365,23 +379,33 @@ updatePackageIndexCacheFile indexFile cacheFile = do
      ++ [ CacheBuildTreeRef blockNo
         | (BuildTreeRef _ _ _ blockNo) <- pkgs]
 
+data ReadPackageIndexMode = ReadPackageIndexStrict
+                          | ReadPackageIndexLazyIO
+
 readPackageIndexCacheFile :: Package pkg
                           => (PackageEntry -> pkg)
                           -> FilePath
                           -> FilePath
+                          -> ReadPackageIndexMode
                           -> IO (PackageIndex pkg, [Dependency])
-readPackageIndexCacheFile mkPkg indexFile cacheFile = do
+readPackageIndexCacheFile mkPkg indexFile cacheFile mode = do
   cache    <- liftM readIndexCache (BSS.readFile cacheFile)
-  withFile indexFile ReadMode $ \indexHnd ->
-    packageIndexFromCache mkPkg indexHnd cache
+  myWithFile indexFile ReadMode $ \indexHnd ->
+    packageIndexFromCache mkPkg indexHnd cache mode
+  where
+    myWithFile f m act = case mode of
+      ReadPackageIndexStrict -> withFile f m act
+      ReadPackageIndexLazyIO -> do indexHnd <- openFile f m
+                                   act indexHnd
 
 
 packageIndexFromCache :: Package pkg
                       => (PackageEntry -> pkg)
                       -> Handle
                       -> [IndexCacheEntry]
+                      -> ReadPackageIndexMode
                       -> IO (PackageIndex pkg, [Dependency])
-packageIndexFromCache mkPkg hnd = accum mempty []
+packageIndexFromCache mkPkg hnd entrs mode = accum mempty [] entrs
   where
     accum srcpkgs prefs [] = do
       -- Have to reverse entries, since in a tar file, later entries mask
@@ -399,7 +423,12 @@ packageIndexFromCache mkPkg hnd = accum mempty []
         pkgtxt <- getEntryContent blockno
         pkg    <- readPackageDescription pkgtxt
         return (pkg, pkgtxt)
-      let srcpkg = mkPkg (NormalPackage pkgid pkg pkgtxt blockno)
+      let srcpkg = case mode of
+            ReadPackageIndexLazyIO ->
+              mkPkg (NormalPackage pkgid pkg pkgtxt blockno)
+            ReadPackageIndexStrict ->
+              pkg `seq` pkgtxt `seq` mkPkg (NormalPackage pkgid pkg
+                                            pkgtxt blockno)
       accum (srcpkg:srcpkgs) prefs entries
 
     accum srcpkgs prefs (CacheBuildTreeRef blockno : entries) = do
diff --git a/cabal-install/Distribution/Client/Sandbox/Index.hs b/cabal-install/Distribution/Client/Sandbox/Index.hs
index 07dd458..c4f4d39 100644
--- a/cabal-install/Distribution/Client/Sandbox/Index.hs
+++ b/cabal-install/Distribution/Client/Sandbox/Index.hs
@@ -19,7 +19,7 @@ module Distribution.Client.Sandbox.Index (
   ) where
 
 import qualified Distribution.Client.Tar as Tar
-import Distribution.Client.IndexUtils ( getSourcePackages )
+import Distribution.Client.IndexUtils ( getSourcePackagesStrict )
 import Distribution.Client.PackageIndex ( allPackages )
 import Distribution.Client.Types ( Repo(..), LocalRepo(..)
                                  , SourcePackageDb(..)
@@ -182,7 +182,8 @@ listBuildTreeRefs verbosity listIgnored path = do
       DontListIgnored -> do
         let repo = Repo { repoKind = Right LocalRepo
                         , repoLocalDir = takeDirectory path }
-        pkgIndex <- fmap packageIndex . getSourcePackages verbosity $ [repo]
+        pkgIndex <- fmap packageIndex
+                    . getSourcePackagesStrict verbosity $ [repo]
         return [ pkgPath | (LocalUnpackedPackage pkgPath) <-
                     map packageSource . allPackages $ pkgIndex ]
 





More information about the ghc-commits mailing list