Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2014-11-07 22:13:28 +0000
committerThomas Watson2014-11-07 22:13:28 +0000
commitd9b63c1587a976988f98635f4388f602f1a4f55e (patch)
tree9d9990b0712710784fc20bd832bc5dfde795457b /bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/container
parent67afa78e319b7bff12529b25790047bd754d23a0 (diff)
downloadrt.equinox.framework-d9b63c1587a976988f98635f4388f602f1a4f55e.tar.gz
rt.equinox.framework-d9b63c1587a976988f98635f4388f602f1a4f55e.tar.xz
rt.equinox.framework-d9b63c1587a976988f98635f4388f602f1a4f55e.zip
Bug 449779 - Deadlock within the OSGi framework
- Introduce and use AtomicLazyInitializer to manage construction of the loader - Remove the monitor lock from ModuleWiring
Diffstat (limited to 'bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/container')
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/container/AtomicLazyInitializer.java76
1 files changed, 76 insertions, 0 deletions
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/container/AtomicLazyInitializer.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/container/AtomicLazyInitializer.java
new file mode 100644
index 000000000..bb72070d5
--- /dev/null
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/container/AtomicLazyInitializer.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2014 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.internal.container;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * A helper class for doing lazy initialization
+ *
+ * @param <V> the type of object to lazy initialize
+ */
+public class AtomicLazyInitializer<V> {
+ private final AtomicReference<V> holder = new AtomicReference<V>();
+
+ /**
+ * Gets the current value. If the value has not been initialized then
+ * {@code null} is returned;
+ * @return the current value
+ */
+ public final V get() {
+ return holder.get();
+ }
+
+ /**
+ * Atomically gets the current initialized value. If the current value is {@code null}
+ * then the supplied initializer is called to create the value returned.
+ * @param initializer the initializer to call if the current value is {@code null}
+ * @return the initialized value. May return {@code null} if initializer returns null.
+ */
+ public final V getInitialized(Callable<V> initializer) {
+ V result = holder.get();
+ if (result != null) {
+ return result;
+ }
+ // Must hold a lock to ensure the operation is atomic.
+ synchronized (holder) {
+ result = holder.get();
+ if (result != null) {
+ return result;
+ }
+ try {
+ result = initializer.call();
+ } catch (Exception e) {
+ unchecked(e);
+ }
+ holder.set(result);
+ return result;
+ }
+ }
+
+ /**
+ * Gets the current value and clears the value for future calls to this lazy initializer.
+ * @return the current value
+ */
+ public final V getAndClear() {
+ return holder.getAndSet(null);
+ }
+
+ private static <T> T unchecked(Exception exception) {
+ return AtomicLazyInitializer.<T, RuntimeException> unchecked0(exception);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T, E extends Exception> T unchecked0(Exception exception) throws E {
+ throw (E) exception;
+ }
+} \ No newline at end of file

Back to the top