schedule :: Scheduler -> UTCTime -> IO () -> IO ()
schedule scheduler when task = locked scheduler $ do
  -- Store the new task
  n <- modifyMVar (counter scheduler) $ \n -> return (n + 1, n)
  modifyMVar_ (tasks scheduler) $ return . Map.insert (when, n) task
  
  -- Kill the old wake-up thread and spawn a new one
  modifyMVar_ (waitTId scheduler) $ \tid -> do
    maybe (return ()) killThread tid
    tid' <- fork (manager scheduler) "Scheduler-run" $ run scheduler
    return $ Just tid'
schedule :: Scheduler -> UTCTime -> IO () -> IO ()
schedule scheduler when task = locked scheduler $ do
  -- Store the new task
  n <- modifyMVar (counter scheduler) $ \n -> return (n + 1, n)
  modifyMVar_ (tasks scheduler) $ return . Map.insert (when, n) task
  
  -- Kill the old wake-up thread and spawn a new one
  modifyMVar_ (waitTId scheduler) $ \tid -> do
    maybe (return ()) killThread tid
    tid' <- fork (manager scheduler) "Scheduler-run" $ run scheduler
    return $ Just tid'
schedule scheduler when task = locked scheduler $ do
  -- Store the new task
  n <- modifyMVar (counter scheduler) $ \n -> return (n + 1, n)
  modifyMVar_ (tasks scheduler) $ return . Map.insert (when, n) task
  
  -- Kill the old wake-up thread and spawn a new one
  modifyMVar_ (waitTId scheduler) $ \tid -> do
    maybe (return ()) killThread tid
    tid' <- fork (manager scheduler) "Scheduler-run" $ run scheduler
    return $ Just tid'