summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit/src/org/eclipse
diff options
context:
space:
mode:
authorThomas Wolf <thomas.wolf@paranor.ch>2022-04-03 20:11:29 +0200
committerThomas Wolf <thomas.wolf@paranor.ch>2022-04-14 10:52:55 +0200
commitfbce3122e0e41b497ac6e2a8176d46f90d302671 (patch)
treefc5e4fc7f1feadbfc5b3241476193daaae40952a /org.eclipse.jgit/src/org/eclipse
parenteca101fc0570e739cc722bf2977973ac2a4ce147 (diff)
downloadjgit-fbce3122e0e41b497ac6e2a8176d46f90d302671.tar.gz
jgit-fbce3122e0e41b497ac6e2a8176d46f90d302671.zip
GpgSigner: prevent class lock inversion on the default signer
Don't store the default signer in a static field of the abstract superclass GpgSigner. This many lead to a lock inversion on the class initialization locks if there are concurrent loads of the GpgSigner class and of one of its subclasses, and that subclass happens to be the one the ServiceLoader wants to load. Use the holder pattern to de-couple the loading of class GpgSigner from the ServiceLoader call. Bug: 579550 Change-Id: Ifac0ea0c8985a09fe0518d0dabc072fafd6db907 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
Diffstat (limited to 'org.eclipse.jgit/src/org/eclipse')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/GpgSigner.java44
1 files changed, 30 insertions, 14 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/GpgSigner.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/GpgSigner.java
index 5b32cf0b5f..b25a61b506 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/GpgSigner.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/GpgSigner.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018, Salesforce. and others
+ * Copyright (C) 2018, 2022 Salesforce and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -26,22 +26,38 @@ import org.slf4j.LoggerFactory;
* @since 5.3
*/
public abstract class GpgSigner {
+
private static final Logger LOG = LoggerFactory.getLogger(GpgSigner.class);
- private static GpgSigner defaultSigner = loadGpgSigner();
+ private static class DefaultSigner {
+
+ private static volatile GpgSigner defaultSigner = loadGpgSigner();
- private static GpgSigner loadGpgSigner() {
- try {
- ServiceLoader<GpgSigner> loader = ServiceLoader
- .load(GpgSigner.class);
- Iterator<GpgSigner> iter = loader.iterator();
- if (iter.hasNext()) {
- return iter.next();
+ private static GpgSigner loadGpgSigner() {
+ try {
+ ServiceLoader<GpgSigner> loader = ServiceLoader
+ .load(GpgSigner.class);
+ Iterator<GpgSigner> iter = loader.iterator();
+ if (iter.hasNext()) {
+ return iter.next();
+ }
+ } catch (ServiceConfigurationError e) {
+ LOG.error(e.getMessage(), e);
}
- } catch (ServiceConfigurationError e) {
- LOG.error(e.getMessage(), e);
+ return null;
+ }
+
+ private DefaultSigner() {
+ // No instantiation
+ }
+
+ public static GpgSigner getDefault() {
+ return defaultSigner;
+ }
+
+ public static void setDefault(GpgSigner signer) {
+ defaultSigner = signer;
}
- return null;
}
/**
@@ -50,7 +66,7 @@ public abstract class GpgSigner {
* @return the default signer, or <code>null</code>.
*/
public static GpgSigner getDefault() {
- return defaultSigner;
+ return DefaultSigner.getDefault();
}
/**
@@ -61,7 +77,7 @@ public abstract class GpgSigner {
* default.
*/
public static void setDefault(GpgSigner signer) {
- GpgSigner.defaultSigner = signer;
+ DefaultSigner.setDefault(signer);
}
/**