diff options
2 files changed, 22 insertions, 18 deletions
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Framework.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Framework.java index d3aeaf645..617db7f49 100644 --- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Framework.java +++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/Framework.java @@ -56,26 +56,26 @@ public class Framework implements EventPublisher, Runnable { private static String JAVASE = "JavaSE-"; //$NON-NLS-1$ private static String PROFILE_EXT = ".profile"; //$NON-NLS-1$ /** FrameworkAdaptor specific functions. */ - protected FrameworkAdaptor adaptor; + protected volatile FrameworkAdaptor adaptor; /** Framework properties object. A reference to the * System.getProperies() object. The properties from * the adaptor will be merged into these properties. */ protected Properties properties; /** Has the framework been started */ - protected boolean active; + protected volatile boolean active; /** Event indicating the reason for shutdown*/ private FrameworkEvent[] shutdownEvent; /** The bundles installed in the framework */ protected BundleRepository bundles; /** Package Admin object. This object manages the exported packages. */ - protected PackageAdminImpl packageAdmin; + protected volatile PackageAdminImpl packageAdmin; /** PermissionAdmin and ConditionalPermissionAdmin impl. This object manages the bundle permissions. */ protected SecurityAdmin securityAdmin; /** Startlevel object. This object manages the framework and bundle startlevels */ protected StartLevelManager startLevelManager; /** The ServiceRegistry */ - private ServiceRegistry serviceRegistry; + private volatile ServiceRegistry serviceRegistry; private final int BSN_VERSION; private static final int BSN_VERSION_SINGLE = 1; private static final int BSN_VERSION_MULTIPLE = 2; @@ -104,7 +104,7 @@ public class Framework implements EventPublisher, Runnable { static final String findHookName = FindHook.class.getName(); static final String collisionHookName = CollisionHook.class.getName(); /** EventManager for event delivery. */ - protected EventManager eventManager; + protected volatile EventManager eventManager; /* Reservation object for install synchronization */ private Map<String, Thread> installLock; /** System Bundle object */ @@ -121,7 +121,7 @@ public class Framework implements EventPublisher, Runnable { * The AliasMapper used to alias OS Names. */ protected static AliasMapper aliasMapper = new AliasMapper(); - SecureAction secureAction = AccessController.doPrivileged(SecureAction.createSecureAction()); + static final SecureAction secureAction = AccessController.doPrivileged(SecureAction.createSecureAction()); // cache of AdminPermissions keyed by Bundle ID private final Map<Long, Map<String, AdminPermission>> adminPermissions = new HashMap<Long, Map<String, AdminPermission>>(); @@ -616,7 +616,6 @@ public class Framework implements EventPublisher, Runnable { eventManager.close(); eventManager = null; } - secureAction = null; packageAdmin = null; adaptor = null; uninstallURLStreamHandlerFactory(); diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseStorage.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseStorage.java index cd6845667..982b8162a 100644 --- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseStorage.java +++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BaseStorage.java @@ -912,7 +912,7 @@ public class BaseStorage implements SynchronousBundleListener { this.context = fwContext; // System property can be set to enable state saver or not. if (Boolean.valueOf(FrameworkProperties.getProperty(BaseStorage.PROP_ENABLE_STATE_SAVER, "true")).booleanValue()) //$NON-NLS-1$ - stateSaver = new StateSaver(); + stateSaver = new StateSaver(adaptor.getState()); } @@ -1249,7 +1249,13 @@ public class BaseStorage implements SynchronousBundleListener { private Thread runningThread = null; private Thread shutdownHook = null; - StateSaver() { + // Bug 383338. Pass the BaseAdaptor state as a constructor argument and + // reuse rather than call adaptor.getState(), and risk an NPE from + // Framework due to a null ServiceRegistry, each time a lock is desired. + private final State lock; + + StateSaver(State lock) { + this.lock = lock; String prop = FrameworkProperties.getProperty("eclipse.stateSaveDelayInterval"); //$NON-NLS-1$ long delayValue = 30000; // 30 seconds. long maxDelayValue = 1800000; // 30 minutes. @@ -1272,8 +1278,7 @@ public class BaseStorage implements SynchronousBundleListener { } public void run() { - State systemState = adaptor.getState(); - synchronized (systemState) { + synchronized (lock) { long firstSaveTime = lastSaveTime; long curSaveTime = 0; long delayTime; @@ -1289,7 +1294,7 @@ public class BaseStorage implements SynchronousBundleListener { // wait for other save requests try { if (!shutdown) - systemState.wait(delayTime); + lock.wait(delayTime); } catch (InterruptedException ie) { // force break from do/while loops curSaveTime = lastSaveTime; @@ -1312,12 +1317,13 @@ public class BaseStorage implements SynchronousBundleListener { } void shutdown() { - State systemState = adaptor.getState(); - Thread joinWith = null; - synchronized (systemState) { + Thread joinWith; + synchronized (lock) { + if (shutdown) + return; // Don't shutdown more than once. Bug 383338. shutdown = true; joinWith = runningThread; - systemState.notifyAll(); // To wakeup sleeping thread. + lock.notifyAll(); // To wakeup sleeping thread. } try { if (joinWith != null) { @@ -1337,8 +1343,7 @@ public class BaseStorage implements SynchronousBundleListener { } void requestSave() { - final State systemState = adaptor.getState(); - synchronized (systemState) { + synchronized (lock) { if (shutdown) return; // do not start another thread if we have already shutdown if (delay_interval == 0) { |