Opened 3 years ago

Closed 2 years ago

#6157 closed feature request (fixed)

Support duplicating a TChan with the current content available.

Reported by: klao Owned by: simonmar
Priority: normal Milestone: 7.8.1
Component: libraries (other) Version: 7.4.2
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case: stm/tests/cloneTChan001
Blocked By: Blocking:
Related Tickets: Differential Revisions:

Description

I propose adding a function to the Control.Concurrent.STM.TChan that duplicates the channel, but with all current content available in the duplicate channel too. Suggestion:

-- |Clone a 'TChan': similar to dupTChan, but the cloned channel starts with the
-- same content available as the original channel.
cloneTChan :: TChan a -> STM (TChan a)
cloneTChan (TChan read write) = do
  readpos <- readTVar read
  new_read <- newTVar readpos
  return (TChan new_read write)

A little bit of context for the proposal. I was writing a function that started getting a bit complicated (I am waiting of either this message or two other messages in order, and there might be some uninteresting messages before I get any of those...) And I realized that this is a parsing problem and we have libraries for those! But, then I had to realize that there is no way to implement for example Parsec's Stream class with the currently available TChan methods. With the proposed cloneTChan it's trivial:

instance Stream (TChan a) STM a where
    uncons chan = do
      chan' <- cloneTChan chan
      x <- readTChan chan'
      return $ Just (x,chan')

And I can imagine some other applications where the new function would come handy.

The same thing also applies to Control.Concurrent.Chan, though there you have other possibilities (eg. you can "convert" a Chan a into an [a] with unsafeInterleaveIO and work on that, which is not a viable option for TChan.)

Change History (3)

comment:1 Changed 3 years ago by igloo

  • difficulty set to Unknown
  • Milestone set to 7.8.1
  • Owner set to simonmar

Thanks for the suggestion. Simon, I think you know best the feasibility and desirability of this.

comment:2 Changed 2 years ago by simonmar

  • Status changed from new to merge
  • Test Case set to stm/tests/cloneTChan001

Looks like I committed this a while ago, but forgot to close the ticket:

commit 3122a9f7ab30f1eb0d70b50cabf29e6da2e20e5e
Author: Simon Marlow <[email protected]>
Date:   Mon Jun 11 12:21:43 2012 +0100

    add cloneTChan (GHC Trac ticket #6157)

I just added a test for good measure.

comment:3 Changed 2 years ago by simonmar

  • Resolution set to fixed
  • Status changed from merge to closed
Note: See TracTickets for help on using tickets.