PROPOSAL: Add newBroadcastChan :: IO (Chan a) to Control.Concurrent.Chan
Ola! Control.Concurrent.STM.TChan has the “newBroadcastTChan :: STM (TChan a)”, this creates a “write-only” TChan to avoid any space leaks when a Chan is written too but never read from (for example, when dupTChan is used to hand a copy to threads). Unfortunately, no such variant seems to exist for the normal Chan? I have the following code: foo :: Chan a -> IO Foo foo broadcast = do newListener <- dupChan broadcast forkIO $ doStuffWith newListener This means the original Chan is never read from and much like the problem with TChan, values keep piling up in the original channel, causing a space leak. I propose adding newBroadcastChan :: IO (Chan a) The obvious Chan equivalent of newBroadcastTChan, which creates a write-only channel without read end, thus avoiding this space leak. Discussion: 2 weeks? Cheers, Merijn
Since some people on IRC asked for an example implementation, two implementations spring to mind: Implementation #1: newBroadcastChan :: IO (Chan a) newBroadcastChan = do hole <- newEmptyMVar readVar <- newMVar (error "reading from a TChan created by newBroadcastTChan; use dupTChan first") writeVar <- newMVar hole return (Chan readVar writeVar) Pros: - Identical to TChan equivalent - Only one extra function to the API Cons: - Accidental reads lead to crash Implementation #2: newtype BroadcastChan a = BChan (MVar (Stream a)) newBroadcastChan :: IO (BroadcastChan a) newBroadcastChan = do hole <- newEmptyMVar writeVar <- newMVar hole return (BChan writeVar) dupFromBroadcastChan :: BroadcastChan a -> IO (Chan a) dupFromBroadcastChan (BChan writeVar) = do hole <- readMVar writeVar newReadVar <- newMVar hole return (Chan newReadVar writeVar) Pros - Prevents accidental reads from write-only Chan Cons - Adds more new stuff to that API? Cheers, Merijn On 09 Sep 2014, at 00:30 , Merijn Verstraaten <merijn@inconsistent.nl> wrote:
Ola!
Control.Concurrent.STM.TChan has the “newBroadcastTChan :: STM (TChan a)”, this creates a “write-only” TChan to avoid any space leaks when a Chan is written too but never read from (for example, when dupTChan is used to hand a copy to threads). Unfortunately, no such variant seems to exist for the normal Chan? I have the following code:
foo :: Chan a -> IO Foo foo broadcast = do newListener <- dupChan broadcast forkIO $ doStuffWith newListener
This means the original Chan is never read from and much like the problem with TChan, values keep piling up in the original channel, causing a space leak. I propose adding
newBroadcastChan :: IO (Chan a)
The obvious Chan equivalent of newBroadcastTChan, which creates a write-only channel without read end, thus avoiding this space leak.
Discussion: 2 weeks?
Cheers, Merijn
participants (1)
-
Merijn Verstraaten