[ZODB-Dev] Exception while closing ZODB

Tim Peters tim at zope.com
Wed Jul 7 13:42:45 EDT 2004


[Ulla Theiss]
> 1. I think, you have understood the problem correctly.
>
> 2. The second problem you mentioned, we have solved by using semaphores
> in the calling class.

How, specifically?  You're trying to open and close the same FileStorage
simultaneously in two threads, and more than one race is possible.  Offhand
I don't see how you were able to truly fix one race without fixing all
related races.

> 3. We really need this functionality. Our application is for much more
> than a year in production. Until Zope 2.6.x (ZODB used the class LockFile
> from winlock) we didn't have this problem. But we had a problem with big 
> memory leaks. At the moment we need reboot Zope 2.6.x about 5 times a day
> (!). The memory problem is solved in Zope 2.7.0. Therefore we really need
> Zope 2.7.0.

The file locking code was rewritten (by someone other than me) for ZODB 3.2
to fix other problems with file locking.  In particular, I see that 3.1
never unlocked lock files on Windows, and I recall that created intractable
problems (because of the "hard"-- non-advisory --nature of Windows file
locks).

> 4. Because most of the time the application works fine and the problem
> only comes up with very particular temporarily behaviour, it needs a lot
> of time to find out the problem.

Of course that's typical of thread races.  I still don't understand why you
*need* to be in the business of trying to both open and close a single
FileStorage simultaneously from multiple threads, but if you believe you
must, and aren't willing to fix it in your calling code, then the intended
semantics need to be defined first (rather than stumbled into, which appears
to be the case in 2.6).  As I said before, it seems inherently ill-defined
to me.

The best I can imagine doing is making the guts of LockFile.__init__ and
LockFile.close mutually exclusive critical sections.  Then if you tried to
both open and close an open FileStorage simultaneously, you would either:

A. Get an exception from trying to open the already-open FileStorage
   (if the thread doing __init__ happened to win the critical-section
   race -- it would try to lock the already-locked lock file then, and
   trying to do so would raise an exception).  If the caller caught that
   exception and retried, it would eventually fall into case #B:

or

B. The FileStorage would first be closed, then opened again (if the
   thread doing close() happened to win the critical-section race).

The other failure modes we discussed in this thread would not occur.



More information about the ZODB-Dev mailing list