úÎ6ƒ5Ò EThis is an opaque type of timeouts. A value of this type is returned G when creating a timeout and can be used to cancel the same timeout. EThis is set, atomically, to true when the manager thread is started.  This thread isn'4t started unless someone actually creates a timeout GWhen a timeout thread times out, it compares the first element of this ? tuple against the value that it was created with. If they don' t match then  it'Hs no longer the current timeout thread and it exits. Otherwise, it sets ( the second element to true and exits. =This is a map of all the timeouts. It maps the absolute time ; that the timeout expires at to a list of tagged actions F to perform at that time. For a given value in the map, the Ints of - every element in the list must be unique. 6Get the list of expired timers from a map of timeouts the current time the timeouts map "the list of actions and a new map .Run the actions for all expired timers in the timeouts global. Update : that global with a new Map, less the expired timeouts. the current time the timeouts map FA version of unfoldr which returns the final value as well. Note that 1 the resulting list comes off in reverse order BThis is a thread which waits for the given number of milliseconds 2 and tries to set the snd element of the global signal to true, iff @ the first element of that global is equal to its tag number. the id of this timeout, see signal the time to wakeup KAdd an action to be performed at some point in the future. The action will L occur inside a thread which is dedicated to performing them so it should 9 run quickly and certainly should not block on IO etc. :the number of seconds in the future to perform the action the action to perform ISimilar in function to addTimeout above, this call splits the IO and STM L parts of the process so that a timeout can be added atomically. Consider  the following code: @ We add a timeout with an action which reads from a global TVar C We add the TimeoutTag (in case we wish to handle the timeout) and K some bookkeeping data to the global TVar and trigger some external ( action (i.e. a network request) KIn this case, the timeout could occur before the bookkeeping is added. Now  the timeout code won'7t find the correct state. If we switch the two actions  then we don'At have the TimeoutTag to add to the bookkeeping structure and we ; would need another TVar, or some such, to fill in later. :the number of seconds in the future to perform the action the action to perform 0an action to add the timeout and return the tag JRemove a timeout. This function never fails, but will return False if the  given timeout couldn'2t be found. This may be because cancelTimeout has I already been called with this tag, or because the timeout has already < fired. Note that, since timeouts are IO actions, they don't run atomically.  Thus it'@s possible that this call returns False and that the timeout is ( currently in the process of running. LNote that one should never call cancelTimeout twice with the same tag since  it'Fs possible that the tag will be reused and thus the second call could  cancel a different timeout. the tag returned by addTimeout !returns False if the timeout didn't exist the current minimum time $the id of the current timeoutThread       control-timeout-0.1.1Control.Timeout TimeoutTag addTimeoutaddTimeoutAtomic cancelTimeoutmanagerThreadStartedsignaltimeouts expiredTimersrunExpiredTimersunfoldrWithValue timeoutThreadtimeoutManagerThread