For what it's worth you can implement this abstraction ontop of channels.
module Control.Concurrent.Chan.Closeable where
import Control.Concurrent.Chan (Chan)
import qualified Control.Concurrent.Chan as C
import Data.Maybe
getChanWhileJust :: Chan (Maybe a) -> IO [a]
getChanWhileJust ch = fmap (catMaybes . takeWhile isJust) (C.getChanContents ch)
-- λ> chan <- newChan :: IO (Chan (Maybe Integer))
-- λ> writeList2Chan chan (map Just [1..10] ++ [Nothing])
-- λ> getChanWhileJust chan
-- [1,2,3,4,5,6,7,8,9,10]