Hello community,
here is the log from the commit of package ghc-enclosed-exceptions for
openSUSE:Factory checked in at 2016-07-21 08:11:50
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-enclosed-exceptions (Old)
and /work/SRC/openSUSE:Factory/.ghc-enclosed-exceptions.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-enclosed-exceptions"
Changes:
--------
---
/work/SRC/openSUSE:Factory/ghc-enclosed-exceptions/ghc-enclosed-exceptions.changes
2016-07-05 09:52:08.000000000 +0200
+++
/work/SRC/openSUSE:Factory/.ghc-enclosed-exceptions.new/ghc-enclosed-exceptions.changes
2016-07-21 08:11:55.000000000 +0200
@@ -1,0 +2,5 @@
+Sun Jul 10 17:29:10 UTC 2016 - [email protected]
+
+- Update to version 1.0.2 revision 1 with cabal2obs.
+
+-------------------------------------------------------------------
Old:
----
enclosed-exceptions-1.0.1.1.tar.gz
New:
----
1.cabal
enclosed-exceptions-1.0.2.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ ghc-enclosed-exceptions.spec ++++++
--- /var/tmp/diff_new_pack.fcAnwr/_old 2016-07-21 08:11:56.000000000 +0200
+++ /var/tmp/diff_new_pack.fcAnwr/_new 2016-07-21 08:11:56.000000000 +0200
@@ -17,67 +17,81 @@
%global pkg_name enclosed-exceptions
-
+%bcond_with tests
Name: ghc-%{pkg_name}
-Version: 1.0.1.1
+Version: 1.0.2
Release: 0
-Summary: Catching all exceptions raised within an enclosed computation
+Summary: Catching all exceptions from within an enclosed computation
License: MIT
Group: System/Libraries
-
-Url: http://hackage.haskell.org/package/%{pkg_name}
-Source0:
http://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz
-BuildRoot: %{_tmppath}/%{name}-%{version}-build
-
-BuildRequires: fdupes
+Url: https://hackage.haskell.org/package/%{pkg_name}
+Source0:
https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz
+Source1:
https://hackage.haskell.org/package/%{pkg_name}-%{version}/revision/1.cabal
BuildRequires: ghc-Cabal-devel
-BuildRequires: ghc-async-devel
+# Begin cabal-rpm deps:
BuildRequires: ghc-deepseq-devel
BuildRequires: ghc-lifted-base-devel
BuildRequires: ghc-monad-control-devel
BuildRequires: ghc-rpm-macros
+BuildRequires: ghc-transformers-base-devel
BuildRequires: ghc-transformers-devel
+BuildRoot: %{_tmppath}/%{name}-%{version}-build
+%if %{with tests}
+BuildRequires: ghc-QuickCheck-devel
+BuildRequires: ghc-async-devel
+BuildRequires: ghc-hspec-devel
+BuildRequires: ghc-stm-devel
+%endif
+# End cabal-rpm deps
%description
-Catching all exceptions raised within an enclosed computation, while
-remaining responsive to (external) asynchronous exceptions.
-
-This package provides the Haskell %{pkg_name} libraries.
+Catching all exceptions raised within an enclosed computation, while remaining
+responsive to (external) asynchronous exceptions. For more information on the
+technique, please see:
+<https://www.fpcomplete.com/user/snoyberg/general-haskell/exceptions/catching-all-exceptions>.
-%package -n ghc-%{pkg_name}-devel
+%package devel
Summary: Haskell %{pkg_name} library development files
Group: Development/Libraries/Other
-Provides: %{name}-static = %{version}-%{release}
Requires: %{name} = %{version}-%{release}
Requires: ghc-compiler = %{ghc_version}
+Requires(post): ghc-compiler = %{ghc_version}
+Requires(postun): ghc-compiler = %{ghc_version}
-%description -n ghc-%{pkg_name}-devel
-Catching all exceptions raised within an enclosed computation, while
-remaining responsive to (external) asynchronous exceptions.
-number type.
-
-This package provides the Haskell %{pkg_name} library development files.
+%description devel
+This package provides the Haskell %{pkg_name} library development
+files.
%prep
%setup -q -n %{pkg_name}-%{version}
+cp -p %{SOURCE1} %{pkg_name}.cabal
+
%build
%ghc_lib_build
+
%install
%ghc_lib_install
-%post -n ghc-%{pkg_name}-devel
+
+%check
+%if %{with tests}
+%{cabal} test
+%endif
+
+
+%post devel
%ghc_pkg_recache
-%postun -n ghc-%{pkg_name}-devel
+%postun devel
%ghc_pkg_recache
-%files -f ghc-%{pkg_name}.files
-%defattr(-,root,root)
+%files -f %{name}.files
+%defattr(-,root,root,-)
%doc LICENSE
-%files -n ghc-%{pkg_name}-devel -f ghc-%{pkg_name}-devel.files
+%files devel -f %{name}-devel.files
%defattr(-,root,root,-)
%changelog
++++++ 1.cabal ++++++
name: enclosed-exceptions
version: 1.0.2
x-revision: 1
synopsis: Catching all exceptions from within an enclosed computation
description: Catching all exceptions raised within an enclosed
computation,
while remaining responsive to (external) asynchronous
exceptions.
For more information on the technique, please see:
<https://www.fpcomplete.com/user/snoyberg/general-haskell/exceptions/catching-all-exceptions>
homepage: https://github.com/jcristovao/enclosed-exceptions
license: MIT
license-file: LICENSE
author: Michael Snoyman, João Cristóvão
maintainer: [email protected], [email protected]
category: Control
build-type: Simple
cabal-version: >=1.8
library
exposed-modules: Control.Exception.Enclosed
hs-source-dirs: src
build-depends: base >= 4.6 && < 5
, transformers
, lifted-base >= 0.2
, monad-control
, deepseq
, transformers-base
ghc-options: -Wall -fno-warn-orphans
test-suite test
hs-source-dirs: src, test
main-is: main.hs
type: exitcode-stdio-1.0
build-depends: base
, lifted-base >= 0.2
, monad-control
, async >= 2.0
, deepseq
, hspec >= 1.3
, QuickCheck
, stm
, transformers
, transformers-base
ghc-options: -Wall
source-repository head
type: git
location: git://github.com/jcristovao/enclosed-exceptions.git
++++++ enclosed-exceptions-1.0.1.1.tar.gz -> enclosed-exceptions-1.0.2.tar.gz
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/enclosed-exceptions-1.0.1.1/enclosed-exceptions.cabal
new/enclosed-exceptions-1.0.2/enclosed-exceptions.cabal
--- old/enclosed-exceptions-1.0.1.1/enclosed-exceptions.cabal 2015-03-24
07:50:47.000000000 +0100
+++ new/enclosed-exceptions-1.0.2/enclosed-exceptions.cabal 2016-06-22
10:03:04.000000000 +0200
@@ -1,5 +1,5 @@
name: enclosed-exceptions
-version: 1.0.1.1
+version: 1.0.2
synopsis: Catching all exceptions from within an enclosed
computation
description: Catching all exceptions raised within an enclosed
computation,
while remaining responsive to (external) asynchronous
exceptions.
@@ -21,7 +21,6 @@
, transformers
, lifted-base >= 0.2
, monad-control
- , async >= 2.0
, deepseq
, transformers-base
ghc-options: -Wall -fno-warn-orphans
@@ -37,6 +36,7 @@
, deepseq
, hspec >= 1.3
, QuickCheck
+ , stm
, transformers
, transformers-base
ghc-options: -Wall
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/enclosed-exceptions-1.0.1.1/src/Control/Exception/Enclosed.hs
new/enclosed-exceptions-1.0.2/src/Control/Exception/Enclosed.hs
--- old/enclosed-exceptions-1.0.1.1/src/Control/Exception/Enclosed.hs
2015-03-24 07:50:47.000000000 +0100
+++ new/enclosed-exceptions-1.0.2/src/Control/Exception/Enclosed.hs
2016-06-22 10:03:04.000000000 +0200
@@ -50,13 +50,16 @@
) where
import Prelude
-import Control.Exception.Lifted
+import Control.Concurrent (forkIOWithUnmask)
+import Control.Concurrent.MVar (newEmptyMVar, putMVar, readMVar)
+import Control.Exception
import Control.Monad (liftM)
import Control.Monad.Base (liftBase)
import Control.Monad.Trans.Control (MonadBaseControl, liftBaseWith, restoreM)
-import Control.Concurrent.Async (withAsync, waitCatch)
import Control.DeepSeq (NFData, ($!!))
+import qualified Control.Exception.Lifted
+
-- | A version of 'catch' which is specialized for any exception. This
-- simplifies usage as no explicit type signatures are necessary.
--
@@ -89,8 +92,38 @@
-- Since 0.5.6
tryAny :: MonadBaseControl IO m => m a -> m (Either SomeException a)
tryAny m =
- liftBaseWith (\runInIO -> withAsync (runInIO m) waitCatch) >>=
+ liftBaseWith (\runInIO -> tryAnyIO (runInIO m)) >>=
either (return . Left) (liftM Right . restoreM)
+ where
+ tryAnyIO :: IO a -> IO (Either SomeException a)
+ tryAnyIO action = do
+ result <- newEmptyMVar
+ bracket
+ (forkIOWithUnmask (\restore -> try (restore action) >>= putMVar
result))
+ (\t -> throwTo t ThreadKilled)
+ (\_ -> retryCount 10 (readMVar result))
+
+ -- If the action supplied by the user ends up blocking on an MVar
+ -- or STM action, all threads currently blocked on such an action will
+ -- receive an exception. In general, this is a good thing from the GHC
+ -- RTS, but it is counter-productive for our purposes, where we know that
+ -- when the user action receives such an exception, our code above will
+ -- unblock and our main thread will not deadlock.
+ --
+ -- Workaround: we retry the readMVar action if we received a
+ -- BlockedIndefinitelyOnMVar. To remain on the safe side and avoid
+ -- deadlock, we cap this at an arbitrary number (10) above so that, if
+ -- there's a bug in this function, the runtime system can still recover.
+ --
+ -- For previous discussion of this topic, see:
+ -- https://github.com/simonmar/async/pull/15
+ retryCount :: Int -> IO a -> IO a
+ retryCount cnt0 action =
+ loop cnt0
+ where
+ loop 0 = action
+ loop cnt = action `catch`
+ \BlockedIndefinitelyOnMVar -> loop (cnt - 1)
-- | An extension to @catch@ which ensures that the return value is fully
-- evaluated. See @tryAny@.
@@ -120,7 +153,7 @@
tryDeep :: (Exception e, NFData a, MonadBaseControl IO m)
=> m a
-> m (Either e a)
-tryDeep m = try $ do
+tryDeep m = Control.Exception.Lifted.try $ do
x <- m
liftBase $ evaluate $!! x
@@ -149,14 +182,14 @@
--
-- Since 0.5.6
handleIO :: MonadBaseControl IO m => (IOException -> m a) -> m a -> m a
-handleIO = handle
+handleIO = Control.Exception.Lifted.handle
-- | A version of 'try' which is specialized for IO exceptions.
-- This simplifies usage as no explicit type signatures are necessary.
--
-- Since 0.5.6
tryIO :: MonadBaseControl IO m => m a -> m (Either IOException a)
-tryIO = try
+tryIO = Control.Exception.Lifted.try
-- |
--
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/enclosed-exceptions-1.0.1.1/test/main.hs
new/enclosed-exceptions-1.0.2/test/main.hs
--- old/enclosed-exceptions-1.0.1.1/test/main.hs 2015-03-24
07:50:47.000000000 +0100
+++ new/enclosed-exceptions-1.0.2/test/main.hs 2016-06-22 10:03:04.000000000
+0200
@@ -11,6 +11,7 @@
import Control.Concurrent (threadDelay)
import Control.Concurrent.Async (async, cancelWith, waitCatch)
import Control.Concurrent.MVar
+import Control.Concurrent.STM
import Control.Exception.Enclosed
import Control.Monad (forever)
@@ -77,6 +78,21 @@
it "doesn't catch exceptions lazily thrown in its pure result" $ do
tryAny `trierCatchesDeep` False
+ let shouldBeShow :: Show a => a -> a -> IO ()
+ shouldBeShow x y = show x `shouldBe` show y
+
+ it "isn't fooled by BlockedIndefinitelyOnMVar" $ do
+ res <- tryAny $ do
+ var <- newEmptyMVar
+ takeMVar (var :: MVar ())
+ res `shouldBeShow` Left (toException BlockedIndefinitelyOnMVar)
+
+ it "isn't fooled by BlockedIndefinitelyOnTVar" $ do
+ res <- tryAny $ do
+ var <- atomically newEmptyTMVar
+ atomically $ takeTMVar (var :: TMVar ())
+ res `shouldBeShow` Left (toException BlockedIndefinitelyOnSTM)
+
describe "tryDeep" $ do
it "catches exceptions thrown from the inside" $ do
tryDeep `trierCatchesInside` True