Skip to content

Commit 2221948

Browse files
Alexey Kuleshevichhvr
authored andcommitted
Fix inconsistent behavior when negative bound is supplied to TBQueue
This switches to using `Natural` for `TBQueue`'s size handling.
1 parent 0568e0d commit 2221948

File tree

4 files changed

+22
-16
lines changed

4 files changed

+22
-16
lines changed

Control/Concurrent/STM/TBQueue.hs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ module Control.Concurrent.STM.TBQueue (
4545
) where
4646

4747
import Data.Typeable
48+
import Numeric.Natural
4849
import GHC.Conc
4950

5051
#define _UPK_(x) {-# UNPACK #-} !(x)
@@ -53,11 +54,11 @@ import GHC.Conc
5354
--
5455
-- @since 2.4
5556
data TBQueue a
56-
= TBQueue _UPK_(TVar Int) -- CR: read capacity
57-
_UPK_(TVar [a]) -- R: elements waiting to be read
58-
_UPK_(TVar Int) -- CW: write capacity
59-
_UPK_(TVar [a]) -- W: elements written (head is most recent)
60-
_UPK_(Int) -- CAP: initial capacity
57+
= TBQueue _UPK_(TVar Natural) -- CR: read capacity
58+
_UPK_(TVar [a]) -- R: elements waiting to be read
59+
_UPK_(TVar Natural) -- CW: write capacity
60+
_UPK_(TVar [a]) -- W: elements written (head is most recent)
61+
_UPK_(Natural) -- CAP: initial capacity
6162
deriving Typeable
6263

6364
instance Eq (TBQueue a) where
@@ -77,8 +78,8 @@ instance Eq (TBQueue a) where
7778
-- then CW := CR - 1; CR := 0
7879
-- else **FULL**
7980

80-
-- |Build and returns a new instance of 'TBQueue'
81-
newTBQueue :: Int -- ^ maximum number of elements the queue can hold
81+
-- | Builds and returns a new instance of 'TBQueue'.
82+
newTBQueue :: Natural -- ^ maximum number of elements the queue can hold
8283
-> STM (TBQueue a)
8384
newTBQueue size = do
8485
read <- newTVar []
@@ -91,7 +92,7 @@ newTBQueue size = do
9192
-- 'TBQueue's using 'System.IO.Unsafe.unsafePerformIO', because using
9293
-- 'atomically' inside 'System.IO.Unsafe.unsafePerformIO' isn't
9394
-- possible.
94-
newTBQueueIO :: Int -> IO (TBQueue a)
95+
newTBQueueIO :: Natural -> IO (TBQueue a)
9596
newTBQueueIO size = do
9697
read <- newTVarIO []
9798
write <- newTVarIO []
@@ -103,11 +104,11 @@ newTBQueueIO size = do
103104
writeTBQueue :: TBQueue a -> a -> STM ()
104105
writeTBQueue (TBQueue rsize _read wsize write _size) a = do
105106
w <- readTVar wsize
106-
if (w /= 0)
107+
if (w > 0)
107108
then do writeTVar wsize $! w - 1
108109
else do
109110
r <- readTVar rsize
110-
if (r /= 0)
111+
if (r > 0)
111112
then do writeTVar rsize 0
112113
writeTVar wsize $! r - 1
113114
else retry
@@ -194,7 +195,7 @@ unGetTBQueue (TBQueue rsize read wsize _write _size) a = do
194195
-- |Return the length of a 'TBQueue'.
195196
--
196197
-- @since 2.5.0.0
197-
lengthTBQueue :: TBQueue a -> STM Int
198+
lengthTBQueue :: TBQueue a -> STM Natural
198199
lengthTBQueue (TBQueue rsize _read wsize _write size) = do
199200
r <- readTVar rsize
200201
w <- readTVar wsize

changelog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66

77
* Add `lengthTBQueue` to `Control.Concurrent.STM.TBQueue`.
88

9+
* Switched `newTBQueue` and `newTBQueueIO` to accept `Natural` as
10+
size. [#17](https://github.com/haskell/stm/pull/17)
11+
12+
* Dropped support for `base < 4.8`, due to above change.
13+
914
----
1015

1116
#### 2.4.5.1 *Sep 2018*

testsuite/src/Issue17.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ import Test.HUnit.Base (assertBool, assertEqual)
1414

1515
main :: IO ()
1616
main = do
17-
-- New queue capacity is set to a negative numer
18-
queueIO <- newTBQueueIO (-1 :: Int)
17+
-- New queue capacity is set to 0
18+
queueIO <- newTBQueueIO 0
1919
assertNoCapacityTBQueue queueIO
2020

21-
-- Same as above, except created within STM and different negative number
22-
queueSTM <- atomically $ newTBQueue (minBound :: Int)
21+
-- Same as above, except created within STM
22+
queueSTM <- atomically $ newTBQueue 0
2323
assertNoCapacityTBQueue queueSTM
2424

2525
assertNoCapacityTBQueue :: TBQueue Int -> IO ()

testsuite/src/Issue9.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ main :: IO ()
1515
#if MIN_VERSION_stm(2,4,5)
1616
main = do
1717
-- New queue with capacity 5
18-
queue <- newTBQueueIO (5 :: Int)
18+
queue <- newTBQueueIO 5
1919

2020
-- Fill it up with [1..5]
2121
for_ [1..5] $ \i ->

0 commit comments

Comments
 (0)