aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Ross2011-11-17 06:47:50 (EST)
committerJohn Ross2011-11-17 06:50:37 (EST)
commit85bfc05eb6f0efe5416b57ae7e925f3a1000686f (patch)
treed4ea52a94ac5d02c49a0a4b78842ddfda16f8156
parentff55d9968fcc1526a8df8bbd78cf291b3a657b93 (diff)
downloadrt.equinox.bundles-85bfc05eb6f0efe5416b57ae7e925f3a1000686f.zip
rt.equinox.bundles-85bfc05eb6f0efe5416b57ae7e925f3a1000686f.tar.gz
rt.equinox.bundles-85bfc05eb6f0efe5416b57ae7e925f3a1000686f.tar.bz2
Bug 362137: Support for coordination maximum timeout.v20111117-1150
I added support for a new property named org.eclipse.equinox.coordinator.timeout. The value is in milliseconds. The default value is 0. The property is retrieved using the coordinator's BundleContext.getProperty. The property is retrieved anew with each instantiation of a Coordinator service. If a client attempts to create a coordination with a timeout less than the maximum timeout (when max timeout != 0), the requested timeout will be overwritten with the max timeout. If max timeout != 0, clients will not be able to extend the timeout of a coordination beyond the max.
-rw-r--r--bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinationImpl.java28
-rw-r--r--bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorImpl.java19
-rw-r--r--bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorServiceFactory.java11
-rw-r--r--bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/Messages.java1
-rw-r--r--bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/messages.properties1
5 files changed, 51 insertions, 9 deletions
diff --git a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinationImpl.java b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinationImpl.java
index 3325ae6..ac39a6c 100644
--- a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinationImpl.java
+++ b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinationImpl.java
@@ -37,6 +37,7 @@ public class CoordinationImpl {
private Date deadline;
private CoordinationImpl enclosingCoordination;
private Thread thread;
+ private long totalTimeout;
private TimerTask timerTask;
private final CoordinatorImpl coordinator;
@@ -53,7 +54,7 @@ public class CoordinationImpl {
validateTimeout(timeout);
this.id = id;
this.name = name;
- this.deadline = new Date(System.currentTimeMillis() + timeout);
+ totalTimeout = timeout;
this.coordinator = coordinator;
participants = Collections.synchronizedList(new ArrayList<Participant>());
variables = new HashMap<Class<?>, Object>();
@@ -192,6 +193,25 @@ public class CoordinationImpl {
// existing deadline. The deadline will not be null if timerTask is not null.
if (timeInMillis == 0)
return deadline.getTime();
+ long maxTimeout = coordinator.getMaxTimeout();
+ long newTotalTimeout = totalTimeout + timeInMillis;
+ // If there is no maximum timeout, there's no need to track the total timeout.
+ if (maxTimeout != 0) {
+ // If the max timeout has already been reached, return 0 indicating that no
+ // extension has taken place.
+ if (totalTimeout == maxTimeout)
+ return 0;
+ // If the extension would exceed the maximum timeout, add as much time
+ // as possible.
+ else if (newTotalTimeout > maxTimeout) {
+ totalTimeout = maxTimeout;
+ // Adjust the requested extension amount with the allowable amount.
+ timeInMillis = newTotalTimeout - maxTimeout;
+ }
+ // Otherwise, accept the full extension.
+ else
+ totalTimeout = newTotalTimeout;
+ }
// Cancel the current timeout.
boolean cancelled = timerTask.cancel();
if (!cancelled) {
@@ -338,10 +358,6 @@ public class CoordinationImpl {
return referent;
}
- synchronized Date getDeadline() {
- return deadline;
- }
-
LogService getLogService() {
return coordinator.getLogService();
}
@@ -353,6 +369,8 @@ public class CoordinationImpl {
synchronized void setTimerTask(TimerTask timerTask) {
this.timerTask = timerTask;
+ deadline = new Date(System.currentTimeMillis() + totalTimeout);
+ coordinator.schedule(timerTask, deadline);
}
synchronized void setThreadAndEnclosingCoordination(Thread t, CoordinationImpl c) {
diff --git a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorImpl.java b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorImpl.java
index d38ee34..94a997a 100644
--- a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorImpl.java
+++ b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorImpl.java
@@ -22,6 +22,7 @@ import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
+import org.eclipse.osgi.util.NLS;
import org.osgi.framework.Bundle;
import org.osgi.service.coordinator.Coordination;
import org.osgi.service.coordinator.CoordinationException;
@@ -89,15 +90,19 @@ public class CoordinatorImpl implements Coordinator {
private final Bundle bundle;
private final List<CoordinationImpl> coordinations;
private final LogService logService;
+ private final long maxTimeout;
private final Timer timer;
private boolean shutdown;
- public CoordinatorImpl(Bundle bundle, LogService logService, Timer timer) {
+ public CoordinatorImpl(Bundle bundle, LogService logService, Timer timer, long maxTimeout) {
this.bundle = bundle;
this.logService = logService;
this.timer = timer;
coordinations = new ArrayList<CoordinationImpl>();
+ if (maxTimeout < 0)
+ throw new IllegalArgumentException(Messages.InvalidTimeInterval);
+ this.maxTimeout = maxTimeout;
}
public boolean addParticipant(Participant participant) throws CoordinationException {
@@ -119,6 +124,13 @@ public class CoordinatorImpl implements Coordinator {
CoordinationWeakReference.processOrphanedCoordinations();
// This method requires the INITIATE permission. No bundle check is done.
checkPermission(CoordinationPermission.INITIATE, name);
+ // Override the requested timeout with the max timeout, if necessary.
+ if (maxTimeout != 0) {
+ if (timeout == 0 || maxTimeout < timeout) {
+ logService.log(LogService.LOG_WARNING, NLS.bind(Messages.MaximumTimeout, timeout, maxTimeout));
+ timeout = maxTimeout;
+ }
+ }
// Create the coordination object itself, which will store its own instance
// of a referent to be returned to clients other than the initiator.
CoordinationImpl coordination = new CoordinationImpl(getNextId(), name, timeout, this);
@@ -141,7 +153,6 @@ public class CoordinatorImpl implements Coordinator {
if (timeout > 0) {
TimerTask timerTask = new CoordinationTimerTask(coordination);
coordination.setTimerTask(timerTask);
- schedule(timerTask, coordination.getDeadline());
}
// Make sure to return the referent targeted towards the initiator here.
return referent;
@@ -241,6 +252,10 @@ public class CoordinatorImpl implements Coordinator {
LogService getLogService() {
return logService;
}
+
+ long getMaxTimeout() {
+ return maxTimeout;
+ }
void purge() {
// Purge the timer of all canceled tasks if we're running on a supportive JCL.
diff --git a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorServiceFactory.java b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorServiceFactory.java
index 86dee19..a6ff44d 100644
--- a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorServiceFactory.java
+++ b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/CoordinatorServiceFactory.java
@@ -19,15 +19,17 @@ import org.osgi.framework.ServiceRegistration;
import org.osgi.service.coordinator.Coordinator;
public class CoordinatorServiceFactory implements ServiceFactory<Coordinator> {
+ private final BundleContext bundleContext;
private final LogTracker logTracker;
private final Timer timer = new Timer(true);
public CoordinatorServiceFactory(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
logTracker = new LogTracker(bundleContext, System.out);
}
public Coordinator getService(Bundle bundle, ServiceRegistration<Coordinator> registration) {
- return new CoordinatorImpl(bundle, logTracker, timer);
+ return new CoordinatorImpl(bundle, logTracker, timer, getMaxTimeout());
}
public void ungetService(Bundle bundle, ServiceRegistration<Coordinator> registration, Coordinator service) {
@@ -36,7 +38,12 @@ public class CoordinatorServiceFactory implements ServiceFactory<Coordinator> {
void shutdown() {
timer.cancel();
-// CoordinatorImpl.reset();
logTracker.close();
}
+
+ private long getMaxTimeout() {
+ String prop = bundleContext.getProperty("org.eclipse.equinox.coordinator.timeout"); //$NON-NLS-1$
+ // Intentionally letting the possible NumberFormatException propagate.
+ return prop == null ? 0 : Long.parseLong(prop);
+ }
}
diff --git a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/Messages.java b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/Messages.java
index 5070fb3..704bb16 100644
--- a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/Messages.java
+++ b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/Messages.java
@@ -34,6 +34,7 @@ public class Messages extends NLS {
public static String CoordinationAlreadyExists;
public static String CanceledTaskNotPurged;
public static String OrphanedCoordinationError;
+ public static String MaximumTimeout;
static {
// initialize resource bundle
diff --git a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/messages.properties b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/messages.properties
index 95b09c2..75aafd8 100644
--- a/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/messages.properties
+++ b/bundles/org.eclipse.equinox.coordinator/src/org/eclipse/equinox/coordinator/messages.properties
@@ -28,3 +28,4 @@ CoordinatorShutdown=This coordinator has been shutdown
CoordinationAlreadyExists=Coordination already exists
CanceledTaskNotPurged=Unable to purge the canceled task
OrphanedCoordinationError=An error occurred while processing orphaned coordination {0} with ID {1}.
+MaximumTimeout=A maximum timeout for coordinations has been set. The requested timeout of {0} will become {1}.