You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2010/09/14 13:30:37 UTC
svn commit: r996845 -
/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerImpl.java
Author: cziegeler
Date: Tue Sep 14 11:30:37 2010
New Revision: 996845
URL: http://svn.apache.org/viewvc?rev=996845&view=rev
Log:
SLING-1737 : Add state management for resources - Fix potential sync issue
Modified:
sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerImpl.java
Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerImpl.java?rev=996845&r1=996844&r2=996845&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerImpl.java (original)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/OsgiInstallerImpl.java Tue Sep 14 11:30:37 2010
@@ -143,31 +143,34 @@ public class OsgiInstallerImpl
final SortedSet<OsgiInstallerTask> tasks = this.computeTasks();
if (tasks.isEmpty() && !tasksToDo && !retriesScheduled) {
- // No tasks to execute - wait until new resources are
- // registered
this.cleanupInstallableResources();
- logger.debug("No tasks to process, going idle");
synchronized (newResources) {
- try {
- newResources.wait();
- } catch (InterruptedException ignore) {}
+ // before we go to sleep, check if new resources arrived in the meantime
+ if ( !this.hasNewResources()) {
+ // No tasks to execute - wait until new resources are
+ // registered
+ logger.debug("No tasks to process, going idle");
+ try {
+ newResources.wait();
+ } catch (InterruptedException ignore) {}
+ logger.debug("Notified of new resources, back to work");
+ }
}
- logger.debug("Notified of new resources, back to work");
- continue;
- }
+ } else {
- retriesScheduled = false;
- // execute tasks
- this.executeTasks(tasks);
- // clean up and save
- this.cleanupInstallableResources();
-
- // Some integration tests depend on this delay, make sure to
- // rerun/adapt them if changing this value
- try {
- Thread.sleep(250);
- } catch (final InterruptedException ignore) {}
+ retriesScheduled = false;
+ // execute tasks
+ this.executeTasks(tasks);
+ // clean up and save
+ this.cleanupInstallableResources();
+
+ // Some integration tests depend on this delay, make sure to
+ // rerun/adapt them if changing this value
+ try {
+ Thread.sleep(250);
+ } catch (final InterruptedException ignore) {}
+ }
}
}
@@ -283,73 +286,82 @@ public class OsgiInstallerImpl
}
/**
+ * Checks if new resources are available.
+ * This method should only be invoked from within a synchronized (newResources) block!
+ */
+ private boolean hasNewResources() {
+ return !this.newResources.isEmpty() || !this.newResourcesSchemes.isEmpty() || !this.urlsToRemove.isEmpty();
+ }
+
+ /**
* This is the heart of the installer - it processes new resources and merges them
* with existing resources.
* The second part consists of detecting the resources to be processsed.
*/
private void mergeNewResources() {
synchronized (newResources) {
- final boolean changed = !this.newResources.isEmpty() || !this.newResourcesSchemes.isEmpty() || !this.urlsToRemove.isEmpty();
- // check for new resource providers (schemes)
- // if we have new providers we have to sync them with existing resources
- for(final Map.Entry<String, List<RegisteredResource>> entry : this.newResourcesSchemes.entrySet()) {
- logger.debug("Processing set of new resources with scheme {}", entry.getKey());
-
- // set all previously found resources that are not available anymore to uninstall
- // if they have been installed - remove resources with a different state
- for(final String entityId : this.persistentList.getEntityIds()) {
- final EntityResourceList group = this.persistentList.getEntityResourceList(entityId);
-
- final List<RegisteredResource> toRemove = new ArrayList<RegisteredResource>();
- boolean first = true;
- for(final RegisteredResource r : group.getResources()) {
- if ( r.getScheme().equals(entry.getKey()) ) {
- logger.debug("Checking {}", r);
- // search if we have a new entry with the same url
- boolean found = false;
- final Iterator<RegisteredResource> m = entry.getValue().iterator();
- while ( !found && m.hasNext() ) {
- final RegisteredResource testResource = m.next();
- found = testResource.getURL().equals(r.getURL());
- }
- if ( !found) {
- logger.debug("Resource {} seems to be removed.", r);
- if ( first && (r.getState() == RegisteredResource.State.INSTALLED
- || r.getState() == RegisteredResource.State.INSTALL)
- || r.getState() == RegisteredResource.State.IGNORED) {
- r.setState(RegisteredResource.State.UNINSTALL);
- } else {
- toRemove.add(r);
+ final boolean changed = this.hasNewResources();
+
+ if ( changed ) {
+ // check for new resource providers (schemes)
+ // if we have new providers we have to sync them with existing resources
+ for(final Map.Entry<String, List<RegisteredResource>> entry : this.newResourcesSchemes.entrySet()) {
+ logger.debug("Processing set of new resources with scheme {}", entry.getKey());
+
+ // set all previously found resources that are not available anymore to uninstall
+ // if they have been installed - remove resources with a different state
+ for(final String entityId : this.persistentList.getEntityIds()) {
+ final EntityResourceList group = this.persistentList.getEntityResourceList(entityId);
+
+ final List<RegisteredResource> toRemove = new ArrayList<RegisteredResource>();
+ boolean first = true;
+ for(final RegisteredResource r : group.getResources()) {
+ if ( r.getScheme().equals(entry.getKey()) ) {
+ logger.debug("Checking {}", r);
+ // search if we have a new entry with the same url
+ boolean found = false;
+ final Iterator<RegisteredResource> m = entry.getValue().iterator();
+ while ( !found && m.hasNext() ) {
+ final RegisteredResource testResource = m.next();
+ found = testResource.getURL().equals(r.getURL());
+ }
+ if ( !found) {
+ logger.debug("Resource {} seems to be removed.", r);
+ if ( first && (r.getState() == RegisteredResource.State.INSTALLED
+ || r.getState() == RegisteredResource.State.INSTALL)
+ || r.getState() == RegisteredResource.State.IGNORED) {
+ r.setState(RegisteredResource.State.UNINSTALL);
+ } else {
+ toRemove.add(r);
+ }
}
}
+ first = false;
+ }
+ for(final RegisteredResource rr : toRemove) {
+ this.persistentList.remove(rr);
}
- first = false;
- }
- for(final RegisteredResource rr : toRemove) {
- this.persistentList.remove(rr);
}
+ logger.debug("Added set of {} new resources with scheme {} : {}",
+ new Object[] {entry.getValue().size(), entry.getKey(), entry.getValue()});
+ newResources.addAll(entry.getValue());
}
- logger.debug("Added set of {} new resources with scheme {} : {}",
- new Object[] {entry.getValue().size(), entry.getKey(), entry.getValue()});
- newResources.addAll(entry.getValue());
- }
- newResourcesSchemes.clear();
+ newResourcesSchemes.clear();
- for(RegisteredResource r : newResources) {
- this.persistentList.addOrUpdate(r);
- }
- newResources.clear();
+ for(RegisteredResource r : newResources) {
+ this.persistentList.addOrUpdate(r);
+ }
+ newResources.clear();
- // Mark resources for removal according to urlsToRemove
- if (!urlsToRemove.isEmpty()) {
- for(final String url : urlsToRemove ) {
- this.persistentList.remove(url);
+ // Mark resources for removal according to urlsToRemove
+ if (!urlsToRemove.isEmpty()) {
+ for(final String url : urlsToRemove ) {
+ this.persistentList.remove(url);
+ }
}
- }
- urlsToRemove.clear();
+ urlsToRemove.clear();
- if ( changed ) {
printResources("Merged");
// persist list
this.persistentList.save();