[Haskell-cafe] STM, orElse and timed read from a channel

Simon Marlow simonmar at microsoft.com
Tue Nov 29 07:29:55 EST 2005


On 29 November 2005 12:08, Tomasz Zielonka wrote:

> On Tue, Nov 29, 2005 at 12:00:03PM -0000, Simon Marlow wrote:
>> threadDelay is IO-only; there's no way to use threadDelay in an STM
>> transaction.  For example, if you want to wait for a TVar to go from
>> Nothing to Just x with a timeout, you could do this:
>> 
>>   readOrTimeout :: TVar (Maybe a) -> Int -> STM (Maybe a)  
>>     readOrTimeout t secs = do timeout <- registerTimeout secs
>>     let check_timeout = do
>>           b <- readTVar timeout
>>           if b then return Nothing else retry
>>         check_t = do
>>           m <- readTVar t
>>           case m of
>>             Nothing -> retry
>>             Just x  -> return x
>>     atomically $ check_timeout `orElse` check_t
> 
> Wouldn't it be
>     readOrTimeout :: TVar (Maybe a) -> Int -> IO (Maybe a)
>                                               ^^
> ?

Sorry, yes.

> Alternatively, it would be nice to have a new STM primitive:
> 
>     wailUntil :: ClockTime -> STM ()
> 
> so you would wait until some time-point passes, not for a number of
> time-units (waiting for a number of time-units wouldn't work because
> of retries). I think it could be efficiently implemented, wouldn't it?

Interesting.  You could use that do wait for idle time, for example:

   atomically $ do
      t <- readTVar last_mouse_click
      waitUntil (t+1000)
      ... 

so this transaction only completes when some idle time has passed since
the last mouse click.

But you could also implement this using registerTimeout, albeit with
some more code and an extra thread, and waitUntil requires an
implementation in the runtime which is not entirely trivial.

Cheers,
	Simon


More information about the Haskell-Cafe mailing list