SLING-7004 : Deadlock at startup in Commons Scheduler
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1805278 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzScheduler.java b/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzScheduler.java
index 795d530..b9e5309 100644
--- a/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzScheduler.java
+++ b/src/main/java/org/apache/sling/commons/scheduler/impl/QuartzScheduler.java
@@ -17,7 +17,6 @@
package org.apache.sling.commons.scheduler.impl;
import java.io.Serializable;
-import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@@ -189,21 +188,6 @@
return this.defaultPoolName;
}
- private SchedulerProxy getScheduler(final String pName) throws SchedulerException {
- final String poolName = getThreadPoolName(pName);
- SchedulerProxy proxy = null;
- synchronized ( this.schedulers ) {
- if ( this.active ) {
- proxy = this.schedulers.get(poolName);
- if ( proxy == null ) {
- proxy = new SchedulerProxy(this.threadPoolManager, poolName);
- this.schedulers.put(poolName, proxy);
- }
- }
- }
- return proxy;
- }
-
/**
* @see org.osgi.framework.BundleListener#bundleChanged(org.osgi.framework.BundleEvent)
*/
@@ -212,38 +196,32 @@
if ( event.getType() == BundleEvent.STOPPED ) {
final Long bundleId = event.getBundle().getBundleId();
- final Map<String, SchedulerProxy> proxies;
synchronized ( this.schedulers ) {
if ( this.active ) {
- proxies = new HashMap<>(this.schedulers);
- } else {
- proxies = Collections.emptyMap();
- }
- }
- for(final SchedulerProxy proxy : proxies.values()) {
- synchronized ( proxy ) {
- try {
- final List<String> groups = proxy.getScheduler().getJobGroupNames();
- for(final String group : groups) {
- final Set<JobKey> keys = proxy.getScheduler().getJobKeys(GroupMatcher.jobGroupEquals(group));
- for(final JobKey key : keys) {
- final JobDetail detail = proxy.getScheduler().getJobDetail(key);
- if ( detail != null ) {
- final String jobName = (String) detail.getJobDataMap().get(QuartzScheduler.DATA_MAP_NAME);
- final Object job = detail.getJobDataMap().get(QuartzScheduler.DATA_MAP_OBJECT);
+ for(final SchedulerProxy proxy : this.schedulers.values()) {
+ try {
+ final List<String> groups = proxy.getScheduler().getJobGroupNames();
+ for(final String group : groups) {
+ final Set<JobKey> keys = proxy.getScheduler().getJobKeys(GroupMatcher.jobGroupEquals(group));
+ for(final JobKey key : keys) {
+ final JobDetail detail = proxy.getScheduler().getJobDetail(key);
+ if ( detail != null ) {
+ final String jobName = (String) detail.getJobDataMap().get(QuartzScheduler.DATA_MAP_NAME);
+ final Object job = detail.getJobDataMap().get(QuartzScheduler.DATA_MAP_OBJECT);
- if ( jobName != null && job != null ) {
- final Long jobBundleId = (Long) detail.getJobDataMap().get(QuartzScheduler.DATA_MAP_BUNDLE_ID);
- if ( jobBundleId != null && jobBundleId.equals(bundleId) ) {
- proxy.getScheduler().deleteJob(key);
- this.logger.debug("Unscheduling job with name {}", jobName);
+ if ( jobName != null && job != null ) {
+ final Long jobBundleId = (Long) detail.getJobDataMap().get(QuartzScheduler.DATA_MAP_BUNDLE_ID);
+ if ( jobBundleId != null && jobBundleId.equals(bundleId) ) {
+ proxy.getScheduler().deleteJob(key);
+ this.logger.debug("Unscheduling job with name {}", jobName);
+ }
}
}
}
}
+ } catch ( final SchedulerException ignore) {
+ // we ignore this as there is nothing to do
}
- } catch ( final SchedulerException ignore) {
- // we ignore this as there is nothing to do
}
}
}
@@ -438,26 +416,20 @@
public void removeJob(final Long bundleId, final String jobName) throws NoSuchElementException {
// as this method might be called from unbind and during
// unbind a deactivate could happen, we check the scheduler first
- final Map<String, SchedulerProxy> proxies;
synchronized ( this.schedulers ) {
if ( this.active ) {
- proxies = new HashMap<>(this.schedulers);
- } else {
- proxies = Collections.emptyMap();
- }
- }
- for(final SchedulerProxy proxy : proxies.values()) {
- synchronized ( proxy ) {
- try {
- final JobKey key = JobKey.jobKey(jobName);
- final JobDetail jobdetail = proxy.getScheduler().getJobDetail(key);
- if (jobdetail != null) {
- proxy.getScheduler().deleteJob(key);
- this.logger.debug("Unscheduling job with name {}", jobName);
- return;
+ for(final SchedulerProxy proxy : this.schedulers.values()) {
+ try {
+ final JobKey key = JobKey.jobKey(jobName);
+ final JobDetail jobdetail = proxy.getScheduler().getJobDetail(key);
+ if (jobdetail != null) {
+ proxy.getScheduler().deleteJob(key);
+ this.logger.debug("Unscheduling job with name {}", jobName);
+ return;
+ }
+ } catch (final SchedulerException ignored) {
+ // ignore
}
- } catch (final SchedulerException ignored) {
- // ignore
}
}
}
@@ -566,12 +538,8 @@
*/
public boolean unschedule(final Long bundleId, final String jobName) {
if ( jobName != null ) {
- final Map<String, SchedulerProxy> proxies;
synchronized ( this.schedulers ) {
- proxies = new HashMap<>(this.schedulers);
- }
- for(final SchedulerProxy proxy : proxies.values()) {
- synchronized ( proxy ) {
+ for(final SchedulerProxy proxy : this.schedulers.values()) {
try {
final JobKey key = JobKey.jobKey(jobName);
final JobDetail jobdetail = proxy.getScheduler().getJobDetail(key);
@@ -607,14 +575,25 @@
throw opts.argumentException;
}
- // as this method might be called from unbind and during
- // unbind a deactivate could happen, we check the scheduler first
- final SchedulerProxy proxy = this.getScheduler(opts.threadPoolName);
- if ( proxy == null ) {
- throw new IllegalStateException("Scheduler is not available anymore.");
- }
+ synchronized ( this.schedulers ) {
+ // as this method might be called from unbind and during
+ // unbind a deactivate could happen, we check the scheduler first
+ final String poolName = getThreadPoolName(opts.threadPoolName);
+ SchedulerProxy proxy = null;
+ synchronized ( this.schedulers ) {
+ if ( this.active ) {
+ proxy = this.schedulers.get(poolName);
+ if ( proxy == null ) {
+ proxy = new SchedulerProxy(this.threadPoolManager, poolName);
+ this.schedulers.put(poolName, proxy);
+ }
+ }
+ }
+ if ( proxy == null ) {
+ throw new IllegalStateException("Scheduler is not available anymore.");
+ }
- synchronized ( proxy ) {
+
final String name;
if ( opts.name != null ) {
// if there is already a job with the name, remove it first