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

Modernize and cleanup locking #72

Merged
merged 2 commits into from
Jun 22, 2016
Merged

Modernize and cleanup locking #72

merged 2 commits into from
Jun 22, 2016

Conversation

jimfulton
Copy link
Member

  • Move from try/finally to with

  • Start phasing out the _lock_acquire/_lock_release shortcuts

  • Replace simpler @locked decorators with with statements.

    I've come to prefer the with style tp the decorator style.
    I think it's clearer.

    (The decorators preceeded the Python with statement.)

    I left the decorators in cases where they were used with preconditions.

This is mostly pretty mechanical, although it got a little delicate in
places and ... tests

- Move from try/finally to with

- Start phasing out the _lock_acquire/_lock_release shortcuts

- Replace simpler @locked decorators with with statements.

  I've come to prefer the with style tp the decorator style.
  I think it's clearer.

  (The decorators preceeded the Python with statement.)

  I left the decorators in cases where they were used with preconditions.

This is mostly pretty mechanical, although it got a little delicate in
places and ... tests
@@ -85,13 +85,13 @@ def __init__(self, name, base=None):

# Allocate locks:
self._lock = utils.RLock()
self.__commit_lock = utils.Lock()
Copy link
Member

Choose a reason for hiding this comment

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

Yay!

@@ -445,11 +442,10 @@ def close_files_remove():
# pack didn't free any data. there's no point in continuing.
close_files_remove()
return None
self._commit_lock_acquire()
self._commit_lock.acquire()
Copy link
Member

Choose a reason for hiding this comment

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

Since acquire/release all occur in the same method, wouldn't this be clearer using with self._commit_lock:?

Copy link
Member

Choose a reason for hiding this comment

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

OK, I see that copyRest -> copyOne temporarily releases the lock. This smells a bit.

Copy link
Member Author

Choose a reason for hiding this comment

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

This packing code is very old and really ought to be updated. But this is out of scope of this PR.

@jimfulton
Copy link
Member Author

@tseaver are you good with this now?

self._commit_lock_acquire = self.__commit_lock.acquire
self._commit_lock_release = self.__commit_lock.release
self._commit_lock_acquire = self._commit_lock.acquire
self._commit_lock_release = self._commit_lock.release
Copy link
Member

Choose a reason for hiding this comment

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

Are these micro-optimizations still worth preserving?

Copy link
Member Author

Choose a reason for hiding this comment

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

They're part of the old inheritance API. :( The comment above explains this.

Copy link
Member

Choose a reason for hiding this comment

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

Ugh, what a terrible pattern: who could have done such a thing? (he asks innocently).

@tseaver
Copy link
Member

tseaver commented Jun 21, 2016

OK to merge even without addressing my release-then-acquire concerns (it still smells like a bug magnet, though).

@jimfulton
Copy link
Member Author

I thought I did address your concerns. Did you see the change I made? The locked regions for the ordinary lock should be very obvious now.

@tseaver
Copy link
Member

tseaver commented Jun 21, 2016

The one that I commented on last me the _commit_lock, which is acquired in one method, held across multiple method invocations, and released later. It is also released-then-acquired two layers down in subclass code.

@jimfulton
Copy link
Member Author

OK, wrt commit lock being held over multiple methods:

a) This is a key aspect of the two-phase commit protocol. At least when we return from voting, we have to be assured that we can commit the modified objects, so we have to prevent modification while in the second phase. Currently, we get the lock in tpc_begin. This is a design flaw. We don't really need to get the vote until tpc_vote, and of course, we should be able to get object-level locks, rather than a global lock. This is related to #69. So, eventually we won't get locks until tpc_vote, but even then, the lock will be acquired in tpc_vote and released in tpc_finish or tpc_abort.

b) This is out of scope of this change. :) Although, I think using with, especially when temporarily releasing the storage lock to acquire the commit lock, makes the logic a little clearer.

@jimfulton jimfulton merged commit 82daec9 into master Jun 22, 2016
@jmuchemb jmuchemb deleted the clean-up-locking branch July 26, 2016 17:46
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.

2 participants