Skip to content
Snippets Groups Projects
This project is mirrored from https://github.com/haskell/Cabal. Pull mirroring updated .
  1. Feb 25, 2022
  2. Feb 24, 2022
  3. Feb 23, 2022
    • Mikolaj Konarski's avatar
      Merge pull request #8012 from haskell/andrea/fix-overlapping-patterns · 86674327
      Mikolaj Konarski authored
      Remove overlapping patterns
    • Andrea Bedini's avatar
      Remove overlapping patterns · 22b700b0
      Andrea Bedini authored
      These two `otherwise`s have been dead code since about 2016 but GHC has
      started warning about them only since 9.2.
      22b700b0
    • Mikolaj Konarski's avatar
      Merge pull request #7995 from robx/cleanup-processes · ddf3ba20
      Mikolaj Konarski authored
      Cleanup around subprocess helpers
    • Mikolaj Konarski's avatar
      Merge pull request #7929 from robx/fix-interrupt · 001e3cc8
      Mikolaj Konarski authored
      Fix concurrency/exception bugs in asyncFetchPackages
    • Robert's avatar
      Add changelog entry · 458bc3a5
      Robert authored
      458bc3a5
    • Robert's avatar
      Use async-safe bracket for withTempFileName · 4a0b05a3
      Robert authored
      If `withTempFileName` receives an asynchronous exception (e.g.
      a canceled async), the bracket cleanup handler will attempt to
      remove the temporary file. This can fail with an IO exception.
      
      Regular bracket then throws that IO exception, swallowing the
      asynchronous exception. To calling code, this appears no different
      from an IO exception thrown from the body, and it won't be able
      to tell that it should be exiting promptly.
      
      This manifests concretely during temporary file clean-up of
      `asyncFetchPackages` on Windows (seen during unit testing in CI),
      where temporary file removal fails (on GHC 8.4), which leads
      to `concurrently` failing to cancel the outstanding download
      because it's handled like a regular download failure.
      4a0b05a3
    • Robert's avatar
      Replace use of 'withAsync' by 'concurrently', to not lose exceptions · deca6e7b
      Robert authored
      This fixes deadlock in asyncFetchPackages:
      
        withAsync action1 (\_ -> action2)
      
      loses exceptions thrown by action1. If in addition, action2
      has a dependency on data produced by action1 (as is the case
      here), this will block indefinitely.
      
      (This bug caused some of the new tests to hang, since after
      the change to use async-safe try, it became easier for
      fetchPackages to throw an exception.)
      deca6e7b
    • Robert's avatar
      Use safe `try` in order to not swallow asynchronous exceptions · d0b268ea
      Robert authored
      This is a step towards fixing interrupt handling during
      asynchronous download.
      
      The concrete bug fixed by this changes is  that `try` catches
      asynchronous exceptions, preventing `withAsync` from interrupting
      it when its `body` action finishes prematurely.
      
      This manifests during `cabal build` when hitting Ctrl-C during
      download, e.g.:
      
      1. Ctrl-C interrupts a curl process
      2. This interrupt is converted into a UserInterrupt exception
         via the process package's delegate_ctlc functionality.
      3. UserInterrupt bubbles up through `fetchPackage`, is caught by
         the `try` (fine) and writen to the result mvar.
         Meanwhile, `fetchPackage` continues its loop, starting to
         fetch the next package.
      4. Some `rebuildTarget` is waiting for the interrupted download;
        `waitAsyncFetchPackage` rethrows UserInterrupt in that thread.
      5. UserInterrupt bubbles up through `collectJob`, `execute`, the
         `body` action.
      6. `withAsync`'s finalizer cancels the `fetchPackages` async.
      7. The `fetchPackages` async receives the AsyncCancelled exception
         while fetching the next package (see 3. above). This interrupts
         the download action (it shouldn't matter whether we happen to
         be running curl again or not), and AsyncCancelled bubbles up
         through `fetchPackage`, is caught by the `try` (not fine!) and
         written to the mvar. But no-one is reading that mvar anymore
         because the build job already aborted (step 5), and that
         AsyncCancelled exception is lost.
      8. `fetchPackages` keeps doing its thing, exiting eventually.
      
      Note that this change affects both instances of `try` in this story:
      `UserInterrupt` is also an asynchronous exception, so after the
      change the `UserInterrupt` takes a different path from step 3.
      Followup commits fix bugs along those paths.
      d0b268ea
    • Robert's avatar
      2dc2041f
    • Robert's avatar
      Add dependency on 'safe-exceptions' · 7e81c57d
      Robert authored
      7e81c57d
    • Robert's avatar
      Add some unit tests for asyncFetchPackages · 3e35a521
      Robert authored
      This primarily trigger concurrency bugs that are fixed in the
      follow-up commits.
      3e35a521
    • Robert's avatar
      Extend documentation of asyncFetchPackages · 6652aa58
      Robert authored
      6652aa58
Loading