summaryrefslogtreecommitdiff
path: root/src/Data
diff options
context:
space:
mode:
authorjim@bo <jim@bo>2018-06-21 02:30:05 -0400
committerjim@bo <jim@bo>2018-06-21 02:30:05 -0400
commit458c7a99e07300cde99826f825c3d0d6a7eab298 (patch)
treec57bbf750cfc0b9dc41397fad4075ed5114ce94c /src/Data
parent27c23434f4d7a1ae963c34e307681259bd05f798 (diff)
experimental dequeueOrGetMissing function
Diffstat (limited to 'src/Data')
-rw-r--r--src/Data/PacketQueue.hs18
1 files changed, 18 insertions, 0 deletions
diff --git a/src/Data/PacketQueue.hs b/src/Data/PacketQueue.hs
index f9d9f28f..330934cd 100644
--- a/src/Data/PacketQueue.hs
+++ b/src/Data/PacketQueue.hs
@@ -93,6 +93,24 @@ observeOutOfBand PacketQueue { seqno, qsize, buffend } no = do
93 when ( proj < qsize) $ do 93 when ( proj < qsize) $ do
94 modifyTVar' buffend (\be -> if be - low <= proj then no + 1 else be) 94 modifyTVar' buffend (\be -> if be - low <= proj then no + 1 else be)
95 95
96-- | If buffend < seqno then return expected packet numbers for all
97-- the Nothings in the array between them.
98-- Otherwise, behave as 'dequeue' would.
99dequeueOrGetMissing :: PacketQueue a -> STM (Either [Word32] a)
100dequeueOrGetMissing PacketQueue { pktq, seqno, qsize, buffend } = do
101 i0 <- readTVar seqno
102 be <- readTVar buffend
103 if i0 < be
104 then do
105 maybes <- mapM (readArray pktq) (take (fromIntegral qsize) $ map (`mod` qsize) [ be .. i0 ])
106 let nums = map fst . filter (isNothing . snd) $ zip [be ..] maybes
107 return (Left nums)
108 else do
109 let i = i0 `mod` qsize
110 x <- maybe retry return =<< readArray pktq i
111 writeArray pktq i Nothing
112 modifyTVar' seqno succ
113 return (Right x)
96 114
97-- | Retry until the next expected packet is enqueued. Then return it. 115-- | Retry until the next expected packet is enqueued. Then return it.
98dequeue :: PacketQueue a -> STM a 116dequeue :: PacketQueue a -> STM a