git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[JGIT PATCH 01/13] Fix invalid "double checked locking" in InflaterCache

From
Shawn O. Pearce <spearce@spearce.org>
Date
Dec 23, 2008, 00:27 UTC
Message-ID
<1229992043-1053-2-git-send-email-spearce@spearce.org>
In-Reply-To
<1229992043-1053-1-git-send-email-spearce@spearce.org>

We move the Inflater allocation out of the synchronized block as it requires JNI code to build the libz structure. This permits other threads to get into the Inflater allocation faster.

We also fix the release implementation to validate the array size only after we enter the lock, rather than before. This prevents us from releasing an inflater due to a stale copy of the open count being in our processor cache.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 .../src/org/spearce/jgit/lib/InflaterCache.java    |   31 ++++++++++---------
 1 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/InflaterCache.java b/org.spearce.jgit/src/org/spearce/jgit/lib/InflaterCache.java
index f0f9139..578911c 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/InflaterCache.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/InflaterCache.java
@@ -59,13 +59,18 @@
 	 * 
 	 * @return an available inflater. Never null.
 	 */
-	public synchronized static Inflater get() {
+	public static Inflater get() {
+		final Inflater r = getImpl();
+		return r != null ? r : new Inflater(false);
+	}
+
+	private synchronized static Inflater getImpl() {
 		if (openInflaterCount > 0) {
 			final Inflater r = inflaterCache[--openInflaterCount];
 			inflaterCache[openInflaterCount] = null;
 			return r;
 		}
-		return new Inflater(false);
+		return null;
 	}
 
 	/**
@@ -76,23 +81,19 @@ public synchronized static Inflater get() {
 	 *            does nothing.
 	 */
 	public static void release(final Inflater i) {
-		if (i == null)
-			return;
-
-		if (openInflaterCount == SZ) {
-			i.end();
-			return;
+		if (i != null) {
+			i.reset();
+			if (releaseImpl(i))
+				i.end();
 		}
-
-		i.reset();
-		releaseImpl(i);
 	}
 
-	private static synchronized void releaseImpl(final Inflater i) {
-		if (openInflaterCount == SZ)
-			i.end();
-		else
+	private static synchronized boolean releaseImpl(final Inflater i) {
+		if (openInflaterCount < SZ) {
 			inflaterCache[openInflaterCount++] = i;
+			return false;
+		}
+		return true;
 	}
 
 	private InflaterCache() {
-- 
1.6.1.rc4.301.g5497a
Previous: Shawn O. PearceNext: Shawn O. Pearce
Message 2 of 17 in “Add receive-pack server side support”
  1. 00/13 Add receive-pack server side supportShawn O. Pearce, Dec 23, 2008
  2. 01/13 Fix invalid "double checked locking" in InflaterCacheShawn O. Pearce, Dec 23, 2008
  3. 02/13 Cleanup stupid release of the cached Inflater in IndexPackShawn O. Pearce, Dec 23, 2008
  4. 03/13 Cache an Inflater inside a WindowCursor and reuse it as much as possibleShawn O. Pearce, Dec 23, 2008
  5. 04/13 Make RefDatabase thread-safeShawn O. Pearce, Dec 23, 2008
  6. 05/13 Make PackFile thread-safeShawn O. Pearce, Dec 23, 2008
  7. 06/13 Make Repository thread-safeShawn O. Pearce, Dec 23, 2008
  8. 07/13 Don't open a PackFile multiple times on scanForPacksShawn O. Pearce, Dec 23, 2008
  9. 08/13 Expose RepositoryConfig.getBoolean so applications can use itShawn O. Pearce, Dec 23, 2008
  10. 09/13 Add AnyObjectId.copyTo(StringBuilder)Shawn O. Pearce, Dec 23, 2008
  11. 10/13 Add compare-and-swap semantics to RefUpdateShawn O. Pearce, Dec 23, 2008
  12. 11/13 Allow null new ObjectId during RefUpdate.deleteShawn O. Pearce, Dec 23, 2008
  13. 12/13 Implement the git-receive-pack process in JavaShawn O. Pearce, Dec 23, 2008
  14. 13/13 Add basic git daemon support to publish receive-packShawn O. Pearce, Dec 23, 2008
  15. Robin RosenbergJan 3, 2009
  16. Permit a wider range of repository names in jgit daemon requestsShawn O. Pearce, Jan 5, 2009
  17. Robin RosenbergJan 5, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.