Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(lock): raise LockNotOwnedError when release a lock from non-owned… #3534

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

shenxiangzhuang
Copy link

@shenxiangzhuang shenxiangzhuang commented Feb 27, 2025

Fix #3535

Pull Request check-list

Please make sure to review and check all of these items:

  • Do tests and lints pass with this change?
  • Do the CI tests pass with this change (enable it first in your forked repo and wait for the github action build to finish)?
  • Is the new or changed code fully tested?
  • Is a documentation update included (if this change modifies existing APIs, or introduces new ones)?
  • Is there an example added to the examples folder (if applicable)?
  • Was the change added to CHANGES file?

NOTE: these things are not required to open a PR and can be done
afterwards / while the PR is open.

Description of change

We can get expect result for the test code in #3535 with this implementation:

Thread 2: Lock error: Cannot release a lock that's no longer owned

@petyaslavova
Copy link
Collaborator

Hi @shenxiangzhuang, thank you for your contribution! Your change will be reviewed soon.

Copy link
Collaborator

@petyaslavova petyaslavova left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the original code, we have the following:

def release(self) -> None:
        """
        Releases the already acquired lock
        """
        expected_token = self.local.token
        if expected_token is None:
            raise LockError("Cannot release an unlocked lock", lock_name=self.name)
        self.local.token = None
        self.do_release(expected_token)

This code can raise the LockError in several cases(Refering in some of the cases to the example in the reported issue):

  1. When the token object is not initialized or is already reset to None - it can happen if in thread 1 we have already called release and we call it again - in this case, the error handling is fine - the lock has really been already unlocked.
  2. We are in another thread that hasn't acquired a lock - which sounds like the message and meaning of LockNotOwnedError
  3. We might get in a similar to the first situation using the locks with context manager and trying to call the release function additionally.

If we are in Thread1 and we call release after the lock has expired, we get to self.do_release(expected_token) which raises the LockNotOwnedError with message "Cannot release a lock that's no longer owned" - which sound correct.

Overall I think that we can just change the Exception to LockNotOwnedError(won't be breaking change, because it is a subtype of the LockError) with a proper error message, something like "Cannot release a lock that's not owned or is already unlocked."

@shenxiangzhuang
Copy link
Author

Overall I think that we can just change the Exception to LockNotOwnedError(won't be breaking change, because it is a subtype of the LockError) with a proper error message, something like "Cannot release a lock that's not owned or is already unlocked."

I think it does a more proper way to ease the problem in #3535 and I have changed the code, please review it again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Release a lock from a non-owned thread should raise proper error
2 participants