How does one block until the earlier of (1) a keypress or (2) a previously input time of day in hh:mm format is reached. I am using Windows in case that matters. This DOS assembler program (which does run on Windows too) does what I want via something like batchman waittil 16:30 from the Windows console but I want to do it entirely in Haskell, (i.e. without making use of that program).
How does one block until the earlier of (1) a keypress or (2) a
Share
You can start two threads: one reads a character, the other waits until the specified time is reached; they both write to a single
MVarto signal completion.This is a little tricky, but mostly due to the details: we want to have
stdinin unbuffered and non-echoing mode so that a single keypress stops the waiting without printing anything, and then restore the original state afterwards; and we also need to kill both threads after either finishes, so that we, for example, stop reading fromstdinonce the timeout expires. Additionally, we need to ensure things are cleaned up properly if an exception occurs.bracketsimplifies the clean-up logic here, but it’s still pretty ugly:Even after all that, this solution still doesn’t handle waiting until a specific time — just waiting a certain number of microseconds. For turning a time of day into a number of microseconds to sleep, this previous SO question may help. If the sleeps are sufficiently long, then they might not fit into an
Intof microseconds, so you might have to usethreadDelayin a loop, ordelayfrom the unbounded-delays package.