Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java4
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java9
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_329254_Test.java12
-rw-r--r--plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/util/tests/AbstractOMTest.java10
-rw-r--r--plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/concurrent/TrackableTimerTask.java123
-rw-r--r--plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/om/monitor/AbstractMonitor.java18
6 files changed, 160 insertions, 16 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java
index 5320675c9e..0fef9e2e66 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreAccessor.java
@@ -75,6 +75,7 @@ import org.eclipse.net4j.util.StringUtil;
import org.eclipse.net4j.util.collection.CloseableIterator;
import org.eclipse.net4j.util.collection.Pair;
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
+import org.eclipse.net4j.util.concurrent.TrackableTimerTask;
import org.eclipse.net4j.util.io.IOUtil;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
@@ -105,7 +106,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.TimerTask;
/**
* @author Eike Stepper
@@ -1372,7 +1372,7 @@ public class DBStoreAccessor extends StoreAccessor implements IDBStoreAccessor,
/**
* @author Stefan Winkler
*/
- private static final class ConnectionKeepAliveTask extends TimerTask
+ private static final class ConnectionKeepAliveTask extends TrackableTimerTask
{
public static final long EXECUTION_PERIOD = 1000 * 60 * 60 * 4; // 4 hours
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java
index 06ca4b1b4d..4c1e469114 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/AbstractMappingStrategy.java
@@ -528,15 +528,16 @@ public abstract class AbstractMappingStrategy extends Lifecycle implements IMapp
finally
{
schemaTransaction.close();
- if (async != null)
- {
- async.stop();
- }
}
}
}
finally
{
+ if (async != null)
+ {
+ async.stop();
+ }
+
if (packageRegistryCommitLock != null)
{
systemPackageMappingInfo.ecoreMapped |= ecoreNew;
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_329254_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_329254_Test.java
index e5ddeb5b2d..2226749082 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_329254_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_329254_Test.java
@@ -176,8 +176,8 @@ public class Bugzilla_329254_Test extends AbstractCDOTest
thread11.start();
thread21.start();
- thread11.join();
- thread21.join();
+ thread11.join(DEFAULT_TIMEOUT);
+ thread21.join(DEFAULT_TIMEOUT);
transaction22.waitForUpdate(transaction11async.getLastCommitTime(), DEFAULT_TIMEOUT);
transaction22.waitForUpdate(transaction21async.getLastCommitTime(), DEFAULT_TIMEOUT);
@@ -282,8 +282,8 @@ public class Bugzilla_329254_Test extends AbstractCDOTest
commitThread1.start();
commitThread2.start();
- commitThread1.join();
- commitThread2.join();
+ commitThread1.join(DEFAULT_TIMEOUT);
+ commitThread2.join(DEFAULT_TIMEOUT);
transaction1.waitForUpdate(transaction3.getLastCommitTime(), DEFAULT_TIMEOUT);
transaction1.waitForUpdate(transaction2.getLastCommitTime(), DEFAULT_TIMEOUT);
@@ -381,8 +381,8 @@ public class Bugzilla_329254_Test extends AbstractCDOTest
commitThread1.start();
commitThread2.start();
- commitThread1.join();
- commitThread2.join();
+ commitThread1.join(DEFAULT_TIMEOUT);
+ commitThread2.join(DEFAULT_TIMEOUT);
transaction1.waitForUpdate(transaction3.getLastCommitTime(), DEFAULT_TIMEOUT);
transaction1.waitForUpdate(transaction2.getLastCommitTime(), DEFAULT_TIMEOUT);
diff --git a/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/util/tests/AbstractOMTest.java b/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/util/tests/AbstractOMTest.java
index bd8427a724..5ae8866c0d 100644
--- a/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/util/tests/AbstractOMTest.java
+++ b/plugins/org.eclipse.net4j.tests/src/org/eclipse/net4j/util/tests/AbstractOMTest.java
@@ -14,6 +14,7 @@ import org.eclipse.net4j.internal.util.test.TestExecuter;
import org.eclipse.net4j.tests.bundle.OM;
import org.eclipse.net4j.util.ReflectUtil;
import org.eclipse.net4j.util.concurrent.ConcurrencyUtil;
+import org.eclipse.net4j.util.concurrent.TrackableTimerTask;
import org.eclipse.net4j.util.event.EventUtil;
import org.eclipse.net4j.util.event.IListener;
import org.eclipse.net4j.util.io.IORuntimeException;
@@ -203,6 +204,15 @@ public abstract class AbstractOMTest extends TestCase
try
{
+ TrackableTimerTask.logConstructionStackTraces(2 * DEFAULT_TIMEOUT);
+ }
+ catch (Exception ex)
+ {
+ IOUtil.print(ex);
+ }
+
+ try
+ {
clearReferences(getClass());
}
catch (Exception ex)
diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/concurrent/TrackableTimerTask.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/concurrent/TrackableTimerTask.java
new file mode 100644
index 0000000000..14fb116af3
--- /dev/null
+++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/concurrent/TrackableTimerTask.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.net4j.util.concurrent;
+
+import org.eclipse.net4j.internal.util.bundle.OM;
+import org.eclipse.net4j.util.om.OMPlatform;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.TimerTask;
+import java.util.WeakHashMap;
+
+/**
+ * @author Eike Stepper
+ * @since 3.3
+ */
+public abstract class TrackableTimerTask extends TimerTask
+{
+ /**
+ * The boolean value of the system property <code>org.eclipse.net4j.util.concurrent.TrackTimerTasks</code>.
+ */
+ public static final boolean TRACK_TIMER_TASKS = Boolean.parseBoolean(OMPlatform.INSTANCE.getProperty(
+ "org.eclipse.net4j.util.concurrent.TrackTimerTasks", "false"));
+
+ private static final Map<TrackableTimerTask, ConstructionInfo> CONSTRUCTION_INFOS = TRACK_TIMER_TASKS ? new WeakHashMap<TrackableTimerTask, ConstructionInfo>()
+ : null;
+
+ protected TrackableTimerTask()
+ {
+ if (TRACK_TIMER_TASKS)
+ {
+ synchronized (CONSTRUCTION_INFOS)
+ {
+ CONSTRUCTION_INFOS.put(this, new ConstructionInfo());
+ }
+ }
+ }
+
+ @Override
+ public boolean cancel()
+ {
+ if (TRACK_TIMER_TASKS)
+ {
+ synchronized (CONSTRUCTION_INFOS)
+ {
+ CONSTRUCTION_INFOS.remove(this);
+ }
+ }
+
+ return super.cancel();
+ }
+
+ public static Collection<Exception> getConstructionStackTraces(long minLifeTimeMillis)
+ {
+ if (!TRACK_TIMER_TASKS)
+ {
+ return Collections.emptyList();
+ }
+
+ long maxTimeStamp = System.currentTimeMillis() - minLifeTimeMillis;
+ Collection<Exception> result = new ArrayList<Exception>();
+
+ synchronized (CONSTRUCTION_INFOS)
+ {
+ for (ConstructionInfo constructionInfo : CONSTRUCTION_INFOS.values())
+ {
+ if (constructionInfo.timeStamp < maxTimeStamp)
+ {
+ result.add(constructionInfo.stackTrace);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ public static void logConstructionStackTraces(long minLifeTimeMillis)
+ {
+ if (TRACK_TIMER_TASKS)
+ {
+ Collection<Exception> constructionStackTraces = getConstructionStackTraces(minLifeTimeMillis);
+ if (!constructionStackTraces.isEmpty())
+ {
+ for (Exception exception : constructionStackTraces)
+ {
+ OM.LOG.info(exception);
+ }
+ }
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private final class ConstructionInfo
+ {
+ public final long timeStamp = System.currentTimeMillis();
+
+ public final Exception stackTrace = getStackTrace();
+
+ private Exception getStackTrace()
+ {
+ try
+ {
+ throw new Exception("The timer task " + TrackableTimerTask.this + " has been constructed here:");
+ }
+ catch (Exception ex)
+ {
+ return ex;
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/om/monitor/AbstractMonitor.java b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/om/monitor/AbstractMonitor.java
index 579e4b54ac..84fbdc893d 100644
--- a/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/om/monitor/AbstractMonitor.java
+++ b/plugins/org.eclipse.net4j.util/src/org/eclipse/net4j/util/om/monitor/AbstractMonitor.java
@@ -11,6 +11,8 @@
package org.eclipse.net4j.util.om.monitor;
import org.eclipse.net4j.internal.util.bundle.OM;
+import org.eclipse.net4j.util.concurrent.TrackableTimerTask;
+import org.eclipse.net4j.util.om.OMPlatform;
import java.util.Timer;
import java.util.TimerTask;
@@ -21,6 +23,9 @@ import java.util.TimerTask;
*/
public abstract class AbstractMonitor implements OMMonitor
{
+ private static final boolean CHECK_BEGIN = Boolean.parseBoolean(OMPlatform.INSTANCE.getProperty(
+ "org.eclipse.net4j.util.om.monitor.CheckBegin", "false"));
+
private static final long NOT_BEGUN = -1;
private double totalWork = NOT_BEGUN;
@@ -138,7 +143,7 @@ public abstract class AbstractMonitor implements OMMonitor
private void checkBegun() throws MonitorCanceledException
{
- if (!hasBegun())
+ if (CHECK_BEGIN && !hasBegun())
{
throw new IllegalStateException("begin() has not been called"); //$NON-NLS-1$
}
@@ -155,7 +160,7 @@ public abstract class AbstractMonitor implements OMMonitor
/**
* @author Eike Stepper
*/
- public static class AsyncTimerTask extends TimerTask implements Async
+ public static class AsyncTimerTask extends TrackableTimerTask implements Async
{
private OMMonitor monitor;
@@ -172,7 +177,7 @@ public abstract class AbstractMonitor implements OMMonitor
{
try
{
- if (!canceled)
+ if (!canceled && monitor != null)
{
double work = 1 - monitor.getWork();
monitor.worked(work / TEN);
@@ -188,7 +193,11 @@ public abstract class AbstractMonitor implements OMMonitor
{
try
{
- monitor.done();
+ if (monitor != null)
+ {
+ monitor.done();
+ }
+
cancel();
}
catch (Exception ex)
@@ -201,6 +210,7 @@ public abstract class AbstractMonitor implements OMMonitor
public boolean cancel()
{
canceled = true;
+ monitor = null;
return super.cancel();
}
}

Back to the top