run :: Scheduler -> IO ()
run scheduler = do
  -- Pick the earliest task
  ((time, _), task) <- locked scheduler $ withMVar (tasks scheduler) $ return . Map.findMin
  
  -- Wait until it's time
  now <- getCurrentTime
  let wait = ceiling $ 10^6 * (toRational $ time `diffUTCTime` now)
  longThreadDelay wait

  -- Remove the task from the queue and run it
  locked scheduler $ do
    modifyMVar_ (tasks scheduler) $ return . Map.deleteMin
    void $ fork (manager scheduler) "Scheduler-exec" task

  -- Schedule next task
  moreTasks <- locked scheduler $ withMVar (tasks scheduler) $ return . not . Map.null
  when (moreTasks) $ run scheduler
run :: Scheduler -> IO ()
run scheduler = do
  -- Pick the earliest task
  ((time, _), task) <- locked scheduler $ withMVar (tasks scheduler) $ return . Map.findMin
  
  -- Wait until it's time
  now <- getCurrentTime
  let wait = ceiling $ 10^6 * (toRational $ time `diffUTCTime` now)
  longThreadDelay wait

  -- Remove the task from the queue and run it
  locked scheduler $ do
    modifyMVar_ (tasks scheduler) $ return . Map.deleteMin
    void $ fork (manager scheduler) "Scheduler-exec" task

  -- Schedule next task
  moreTasks <- locked scheduler $ withMVar (tasks scheduler) $ return . not . Map.null
  when (moreTasks) $ run scheduler
run scheduler = do
  -- Pick the earliest task
  ((time, _), task) <- locked scheduler $ withMVar (tasks scheduler) $ return . Map.findMin
  
  -- Wait until it's time
  now <- getCurrentTime
  let wait = ceiling $ 10^6 * (toRational $ time `diffUTCTime` now)
  longThreadDelay wait

  -- Remove the task from the queue and run it
  locked scheduler $ do
    modifyMVar_ (tasks scheduler) $ return . Map.deleteMin
    void $ fork (manager scheduler) "Scheduler-exec" task

  -- Schedule next task
  moreTasks <- locked scheduler $ withMVar (tasks scheduler) $ return . not . Map.null
  when (moreTasks) $ run scheduler