Return-Path: Delivered-To: apmail-commons-dev-archive@www.apache.org Received: (qmail 45836 invoked from network); 3 Mar 2008 06:35:34 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 3 Mar 2008 06:35:34 -0000 Received: (qmail 32309 invoked by uid 500); 3 Mar 2008 06:35:28 -0000 Delivered-To: apmail-commons-dev-archive@commons.apache.org Received: (qmail 32230 invoked by uid 500); 3 Mar 2008 06:35:28 -0000 Mailing-List: contact dev-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "Jakarta Commons Developers List" Delivered-To: mailing list dev@commons.apache.org Received: (qmail 32221 invoked by uid 99); 3 Mar 2008 06:35:28 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 02 Mar 2008 22:35:28 -0800 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of phil.steitz@gmail.com designates 209.85.142.186 as permitted sender) Received: from [209.85.142.186] (HELO ti-out-0910.google.com) (209.85.142.186) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 03 Mar 2008 06:34:42 +0000 Received: by ti-out-0910.google.com with SMTP id a20so5872580tia.10 for ; Sun, 02 Mar 2008 22:35:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from:to:subject:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; bh=B8fnJqiFGVwD1kgXJnxyD9gF8GSEU1WTUA/8XAnWwr8=; b=ocFeObob3wsybaAGD4NHA2xBtSYN4fmJd3D2C+H08wXfTQlfBdwuFwvmC2ciUb+GIBWgMq87zIykNrUHLRegBHHXONvq+PQSL0FWc/d2B7rawWmb2bpPVEblnzksRFzMFafpcR2bYVmwgTOZE79VUJbg5kjnTugG1MLkHnAG534= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:to:subject:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=poRntR4eHA+m/NNwE1dub3GvnrpC65jkvUGhkA+pdoLTv7T7n+yG+vVjz3n2NOkY+xuHS40uyrgjgRcyUbJvO5l2QOhnkEkYkmBM6X4Vb99mpANqMHwoJjXYhzWL8XQon6C9IDNbNMB7/Uf8DF2YbcEDOfJN2vBm05nWWaGPpIQ= Received: by 10.142.201.3 with SMTP id y3mr8803371wff.1.1204526100200; Sun, 02 Mar 2008 22:35:00 -0800 (PST) Received: by 10.142.240.12 with HTTP; Sun, 2 Mar 2008 22:35:00 -0800 (PST) Message-ID: <8a81b4af0803022235r14deed0bo75c58c689ae586c0@mail.gmail.com> Date: Sun, 2 Mar 2008 23:35:00 -0700 From: "Phil Steitz" To: "Jakarta Commons Developers List" Subject: Re: [pool] New DBCP deadlock reported (DBCP-44) In-Reply-To: <47CAA6FC.20801@gmx.de> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline References: <8a81b4af0802290513r2199b2c8v4c94b8e691e8743f@mail.gmail.com> <47C93C1E.7030309@gmx.de> <8a81b4af0803011705t40aed931t248dbbd9e2882761@mail.gmail.com> <47CAA6FC.20801@gmx.de> X-Virus-Checked: Checked by ClamAV on apache.org On Sun, Mar 2, 2008 at 6:09 AM, Christoph Kutzinski wrote: > Hi Phil, > > > Phil Steitz wrote: > > Thanks, Christoph > > > > On Sat, Mar 1, 2008 at 4:21 AM, Christoph Kutzinski wrote: > >> As the 'inversed' locking order in evict() is obviously the source of > >> the problems, I would try to avoid calling any _factory methods while > >> holding the 'this' lock. > > > > +1 > > evict and addObject currently violate this and I think both should be fixed. > > > >> I thinking about something like this: > >> > >> public void evict() { > >> CursorableLinkedList tmpPool; > >> Collection connsToEvict = new ArrayList(); > >> synchronized(this) { > >> tmpPool = new CursorableLinkedList(_pool); > >> } > >> > >> // checking for conns to evict, calling methods on _factory and adding > >> // conns to evict to connsToEvict > >> > >> synchronized(this) { > >> // remove conns in connsToEvict from _pool > >> // ignoring conns that are (currently) not in pool > >> } > >> } > >> > >> Obviuosly, this doesn't work with the evictionCursor as it is > >> implemented now, so it would require some work on that one. > >> > > > > I think something like this might work if we can solve: > > 1) Maintaining the cycling behavior of the evictionCursor - will be > > tricky, but should be doable. > > I haven't looked into the implementation, but I think this shouldn't be > to hard. Especially if one would do only a 'best effort' approach, i.e. > it would be possible that pooled objects are skipped or are repeatedly > checked, a simple index into the _pool should be ok. Or am I missing > something? > No, you are not missing anything. This should not be hard. > > > > 2) "ignoring conns that are > > (currently) not in pool" in the second synch block - hard to do > > efficiently, but again should be doable > > What problems do you see here? I'm not sure why this shouldn't be > possible to do efficiently > This gets the the issue you have identified below. > > > 3) when to do _factory.destroyObject - can't do this is the > > mid-section because borrowObject could jump in and grab the destroyed > > object. Need some way to prevent that, maybe by locking / marking the > > ObjectTimeStampPair. > > That could be done after the second synchronized block, if we remember > only the successful removed objects in connsToEvict (i.e. removing the > ones which couldn't be removed from _pool) > > But that have made me think about a (probably) major flaw in this approach: > It is probably not ok to access a pooled object from within the evictor > thread while it is possibly concurrently accessed from a thread which > borrowed it from the pool (and AFAIS we cannot prevent this scenario > with this approach). > So I also thought about marking the ObjectTimeStampPair as either being > currently 'inEviction' or 'borrowed' or both (volatile boolean fields in > ObjectTimeStampPair). But I fear that this would be vulnerable to > various race conditions. > What race conditions, exactly? Not having thought this through all the way, I was thinking about an integer property that could take one of four values "BORROWED" - a ghost in the pool snapshot "IDLE" - in the pool, OK to borrow "DEAD" - in the pool, marked for eviction "VALIDATING" - in the pool, being validated If we need to synchronize, similarly to AtomicInteger, we could define a synchronized compareAndSet method that borrowObject, returnObject, and evict could use to control access. Synchronization would, as you point out, cost something, but there should not be much contention for these locks. I need to work through the various race conditions, though, to convince myself that a volatile field properly managed would not suffice. Thanks again for your thoughts on this. Phil --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org For additional commands, e-mail: dev-help@commons.apache.org