I think I found the cause of my deadlock, which is (if I'm right that is), located in main.py:912:
val = cache.get(id, cls)
if val is None:
val = cls(_SO_fetch_no_create=1)
We reach this place e.g. by resolving a foreign key through _SO_foreignKey() and get().
If I read the code correctly, the cache's lock is acquired in cache.get() (but not released, which would be done in cache.finishPut(cls)), if the object doesn't already exist. cls(_SO_fetch_no_create=1) then acquires the class' lock through the threadSafeMethod() wrapper in declarative.py.
On the other hand, if I'm creating an object of the same type, at exactly the time between the cache.get() and cls() calls, I'll be able to acquire the class' lock and then pend on the cache's lock, through threadSafe __init__(), then _create(), then _SO_finishCreate(), cacheSet.created(), CacheFactory.created() and finally CashFactory.cull().
This leaves us with the first thread having acquired the cache's lock while pending for the class' lock, and the second thread having acquired the class' lock and pending for the cache's lock -> deadlock. The situation can only occur, if the creation of the object triggers a cache.cull(). In any other case, the cache isn't locked and thus there are no problems.
Does this all make sense?
firstname.lastname@example.org schrieb am 05.07.2007 17:11:20:
> Hi Oleg
> email@example.com schrieb am 05.07.
> 2007 11:31:56:
> > On Thu, Jul 05, 2007 at 11:22:36AM +0200, firstname.lastname@example.org wrote:
> > > The accesses are made in different threads, to objects of the same class
> > > (MyClass in my example). One locks while resolving a ForeignKey in
> > > _SO_foreignKey(), one locks in _SO_finishCreate() and the third one in the
> > > selectresult's __iter__().
> > Can you do an experiment - create objects of OtherClass outside of
> > _create() and assign them to foreign keys after the object has been fully
> > created?
> I've tried to produce an isolated example of my problem. I'm not yet
> sure if everything's needed in here, I'm still trying to buil it further down.
> Things I noticed so far:
> - The _create seems not to have anything to do with it, as it locks
> even without one.
> - A higher number of threads increase the possibility for deadlocks.
> - I need to have two classes, MyClass1 and MyClass2, in order for
> the deadlock to occur.
> To the code:
> - On my machine, the code deadlocks after some 10s of objects created.
> - The threadframe module may be downloaded here: http://www.majid.
> info/mylos/stories/2004/06/10/threadframe.html. Maybe you have some
> clever debugger that can do that for you... :-)
Diese Mitteilung ist nur fuer die Empfaengerin / den Empfaenger bestimmt.
Fuer den Fall, dass sie von nichtberechtigten Personen empfangen wird, bitten wir diese hoeflich, die Mitteilung an die ZKB zurueckzusenden und anschliessend die Mitteilung mit allen Anhaengen sowie allfaellige Kopien zu vernichten bzw. zu loeschen. Der Gebrauch der Information ist verboten.
This message is intended only for the named recipient and may contain confidential or privileged information.
If you have received it in error, please advise the sender by return e-mail and delete this message and any attachments. Any unauthorised use or dissemination of this information is strictly prohibited.