Skip to content

Mutex stays locked when a stop races with unlock #66

Open

Description

@nishino-pfr

Mutex::LockAwaiter can throw CancelledException after unlock() has already handed it the lock, leaving the mutex locked forever.

  1. A coroutine is suspended in co_await mutex.lock().
  2. Its stop is requested. The cancellation is posted and has not run yet.
  3. The holder calls unlock(). resume_now takes the waiter and resumes it; locked_ stays true, as ownership is passed to the waiter.
  4. await_resume sees token.stop_requested() and throws.

Nobody owns the lock now, so locked_ is never cleared and every later lock() waits forever.

This predates #65 (the old check token.stop_requested() && !(active && *active) behaves the same). A fix could be to throw only when the cancellation resumed the waiter (e.g. a cancelled flag set in the register_cancel action, as the other awaiters do), or to unlock before throwing.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions