Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Zope: Dev

Understanding LeakFinder-0.1.1

 

 

Zope dev RSS feed   Index | Next | Previous | View Threaded


rodsenra at gpr

Jan 12, 2005, 11:15 AM

Post #1 of 3 (758 views)
Permalink
Understanding LeakFinder-0.1.1

Hi,

reading LeakFinder's code (version 0.1.1) I was puzzled by:

"""
if not hasattr(DB, '_lf_real_open'):
# Patch DB with a way to block open operations.
DB._open_lock = allocate_lock()
def open(self, *args, **kw):
self._open_lock.acquire()
self._open_lock.release()
return apply(self._lf_real_open, args, kw)
DB._lf_real_open = DB.open
DB.open = open

"""

Inside the redefined::open(), the lock is acquired and
released before delegating to the original::open().
I wonder if:

1) That was done intentionally as a _step_on_the_break_ measure
2) acquire() or release() cause a desired side effect (despite 1),
inside ZODB's inner-sanctum (that eludes me)
3) That was not the original intention, where apply() should come
between acquire() and release()
4) none above (I'd appreciate to learn why)

I've sent this mail to zope-dev because it was the only
address mentioned in the source code.

best regards,
Rod Senra

--
Rodrigo Senra
MSc Computer Engineer rodsenra [at] gpr
GPr Sistemas Ltda http://www.gpr.com.br

_______________________________________________
Zope-Dev maillist - Zope-Dev [at] zope
http://mail.zope.org/mailman/listinfo/zope-dev
** No cross posts or HTML encoding! **
(Related lists -
http://mail.zope.org/mailman/listinfo/zope-announce
http://mail.zope.org/mailman/listinfo/zope )


tim.peters at gmail

Jan 12, 2005, 1:37 PM

Post #2 of 3 (719 views)
Permalink
Re: Understanding LeakFinder-0.1.1 [In reply to]

[Rodrigo Dias Arruda Senra]
> reading LeakFinder's code (version 0.1.1) I was puzzled by:
>
> """
> if not hasattr(DB, '_lf_real_open'):
> # Patch DB with a way to block open operations.
> DB._open_lock = allocate_lock()
> def open(self, *args, **kw):
> self._open_lock.acquire()
> self._open_lock.release()
> return apply(self._lf_real_open, args, kw)
> DB._lf_real_open = DB.open
> DB.open = open
>
> """
>
> Inside the redefined::open(), the lock is acquired and
> released before delegating to the original::open().
> I wonder if:
>
> 1) That was done intentionally as a _step_on_the_break_ measure
> 2) acquire() or release() cause a desired side effect (despite 1),
> inside ZODB's inner-sanctum (that eludes me)
> 3) That was not the original intention, where apply() should come
> between acquire() and release()
> 4) none above (I'd appreciate to learn why)

I'm not familiar with this code (haven't seen it before), but I think
it's clear enough: elsewhere, getControlledRefcounts() acquires this
lock. That prevents the patched DB.open() from calling the real
DB.open() until getControlledRefcounts() releases the lock again. But
I don't see anything to stop getControlledRefcounts() from being
called while any number of other threads are in the midst of the real
DB.open().
_______________________________________________
Zope-Dev maillist - Zope-Dev [at] zope
http://mail.zope.org/mailman/listinfo/zope-dev
** No cross posts or HTML encoding! **
(Related lists -
http://mail.zope.org/mailman/listinfo/zope-announce
http://mail.zope.org/mailman/listinfo/zope )


shane at hathawaymix

Jan 12, 2005, 10:04 PM

Post #3 of 3 (715 views)
Permalink
Re: Understanding LeakFinder-0.1.1 [In reply to]

On Wednesday 12 January 2005 12:15 pm, Rodrigo Dias Arruda Senra wrote:
> Inside the redefined::open(), the lock is acquired and
> released before delegating to the original::open().
> I wonder if:
>
> 1) That was done intentionally as a _step_on_the_break_ measure
> 2) acquire() or release() cause a desired side effect (despite 1),
> inside ZODB's inner-sanctum (that eludes me)
> 3) That was not the original intention, where apply() should come
> between acquire() and release()
> 4) none above (I'd appreciate to learn why)

It's intentional. The quick lock and unlock normally has no effect, but while
getControlledRefcounts is running, it holds _open_lock for several seconds,
preventing new connections. With the lock held, it waits for other
connections to close, clears caches, computes the refcounts, and releases
_open_lock. It does all this to take refcount measurements in a relatively
controlled environment.

Like Tim said, open() calls that start before getControlledRefcounts acquires
_open_lock will not block. getControlledRefcounts does not account for that,
so its call to pools.items() is unreliable. A possible solution is for
getControlledRefcounts to also acquire the database's connection pool lock,
accessible via the _a and _r attributes. But it can't hold that lock for
long, since other threads will need it to close connections.

I didn't know anybody still uses LeakFinder. :-)

Shane
_______________________________________________
Zope-Dev maillist - Zope-Dev [at] zope
http://mail.zope.org/mailman/listinfo/zope-dev
** No cross posts or HTML encoding! **
(Related lists -
http://mail.zope.org/mailman/listinfo/zope-announce
http://mail.zope.org/mailman/listinfo/zope )

Zope dev RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.