Return-Path: Mailing-List: contact torque-dev-help@db.apache.org; run by ezmlm Delivered-To: mailing list torque-dev@db.apache.org Received: (qmail 37713 invoked from network); 20 Jun 2003 07:43:02 -0000 Received: from dsl027-176-145.sfo1.dsl.speakeasy.net (HELO despot) (216.27.176.145) by daedalus.apache.org with SMTP; 20 Jun 2003 07:43:02 -0000 Received: by despot (Postfix, from userid 500) id 63DA7348264; Fri, 20 Jun 2003 00:43:15 -0700 (PDT) Sender: dlr@finemaltcoding.com To: "Turbine Torque Developers List" Subject: Re: TORQUE_3_0_1 CVS Tag References: <3EF25C6A.1090102@backstagetech.com.au> From: Daniel Rall Date: 20 Jun 2003 00:43:15 -0700 Message-ID: Lines: 117 User-Agent: Gnus/5.0808 (Gnus v5.8.8) XEmacs/21.4 (Common Lisp) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N Scott Eade writes: > Shouldn't the TORQUE_3_0_BRANCH have had a TORQUE_3_0_1 > tag added with the release of 3.0.1? > > I guess there is little point if there is not likely to > be a 3.0.2 (i.e. efforts are now focused on 3.1). What do people think about putting this to get this deadlock fix into a 3.0.2? I ask because I have seen it fatal to an entire web application. dlr 2003/06/19 17:41:18 Modified: src/java/org/apache/torque/manager AbstractBaseManager.java MethodResultCache.java Log: Corrected deadly multi-CPU thread deadlock problem discovered by Ed Korthof and John McNally . The problem was due to emulation of synchronization using an int counter (to improve performance by avoiding Java "synchronized" keyword). Post-increment and decrement operators compile to three op codes (with Sun's JDK 1.3.1 for Linux), unsafe on a multi-CPU box. * src/java/org/apache/torque/manager/AbstractBaseManager.java lockCache, inGet, cacheGet(), removeInstanceImpl(), putInstanceImpl(): Removed use of lockeCache and inGet instance fields, replaced by consistent use of Java's "synchronized" keyword (on the current instance, "this"). getMethodResultCache(), addCacheListenerImpl(), createSubsetList(), readObject(): Added JavaDoc. * src/java/org/apache/torque/manager/MethodResultCache.java lockCache, getImpl(), putImpl(), get(): Removed use of lockeCache instance fields, replaced by consistent use of Java's "synchronized" keyword (on the current instance, "this"). remove(): Added error messages to several method overloads. Ed Korthof supplied some test code: Subject: test code demonstrating the lack of atomicity in increment/decrement Date: Wed, 18 Jun 2003 19:16:53 -0700 This took a while to fail on a single CPU box ... but it fails pretty quickly on a multi-cpu box. thanks -- Ed -- +=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-= | Ed Korthof | edk@collab.net | 650-228-2527 | +=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-=+=-= [2. text/plain; test.java]... import java.util.HashMap; public class test { int i = 0; boolean lock = false; HashMap map = new HashMap(); int testThreads = 2; public static void main(String argv[]) throws Exception { new test().runTest(); } public void runTest() throws Exception { map.put("test", new Long(System.currentTimeMillis())); for (int j = 0; j < testThreads; ++j) { Runnable worker = new Runnable() { long current = 0; public void run() { while(true) { if (lock) { synchronized(this) { Object item = map.get("test"); } } else { i++; Long item = (Long)map.get("test"); current += item.longValue() + System.currentTimeMillis(); i--; } } } }; Thread nextThread = new Thread(worker, "worker " + j); nextThread.start(); map.put("worker" + j, nextThread); System.err.println("created worker: " + j + " => " + nextThread); } while (true) { synchronized(this) { lock = true; Thread.yield(); while (i > 0) { System.err.println("i > 0: " + i); Thread.sleep(100); } map.put("test", new Long(System.currentTimeMillis())); lock = false; if (i < 0) { System.err.println("i < 0: " + i); } System.err.println("one iteration"); } Thread.sleep(500); } } }