[PATCH] Singleton Branches

Martin Pool mbp at sourcefrog.net
Thu May 26 16:35:23 BST 2005

On 25 May 2005, John A Meinel <john at arbash-meinel.com> wrote:

> >1. process A acquires read lock
> >2. process B acquires read lock
> >3. process A attempts to acquire write lock.  Blocked on B.
> >4. process B attempts to acquire write lock.  Blocked on A.  Stalemate.
> flock specifically allows you to upgrade a read lock to a write lock. On
> win32 you cannot upgrade a lock.

I think there may be an API (perhaps not exposed in Python) which
allows upgrading.  But the potential deadlock exists anyhow.

> Good point, I was just pointing out that the specific function call
> doesn't allow it. But certainly we can do the unlock anytime you are
> trying to upgrade the lock.
> On the other hand, there are quite a few times where upgrading a lock
> can be decent.
>   1. Process A acquires read lock to do a diff
>   2. Process B acquires read lock to do 'revno()'
>   3. Process A analyses the diff, realizes something needs to change,
>      requests a write lock
>   4. Process B finishes and goes away -> Process A acquires the write lock.

The existence of one non-deadlock path doesn't mean it's safe.

> Admittedly in your example you can get a deadlock. One semi-interesting
> way around it is to have all locks timeout. In a special case
> msvcrt.locking() actually tries for 10 seconds, and then fails. You
> could do a similar thing, just attempt a write lock in non-blocking mode
> for 10 seconds, and if you fail, throw an exception. Pretty easy to do,
> and most operations should finish in a reasonable time, or you don't
> really want to wait for them anyway.

OK, so you can avoid[*] the deadlock if you say that all callers must
be prepared to have their request to upgrade result in loss of the
lock altogether, causing the caller to probably either fall altogether
or start again from the begining with the proper lock.  (And once you
do that, you don't actually need lock upgrading anymore and perhaps
you should not bother, except that it's a complexifying optimization
for the uncontested case.)

[*] http://www.cs.jhu.edu/~yairamir/cs418/os4/tsld011.htm

> Well, one nice possibility of a singleton, is that you can upgrade the
> singleton and everyone goes through the same object and sees the same
> updates.

A singleton is not really a total solution because it won't be unique
among all Python processes, and on the other hand there might be
uncoordinated Python thread-like entities in a single process that
don't want a singleton.

I can see that some applications will want to naively try to create
branch objects and have them uniquified, but I'm not sure that all
will want that, or that it really belongs in the Branch class.


More information about the bazaar mailing list