Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/TeamThreadManager.java')
-rw-r--r--plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/TeamThreadManager.java121
1 files changed, 121 insertions, 0 deletions
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/TeamThreadManager.java b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/TeamThreadManager.java
new file mode 100644
index 000000000..e6bc9db92
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/objectteams/TeamThreadManager.java
@@ -0,0 +1,121 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2006-2010 Berlin Institute of Technology, 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
+ *
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ *
+ * Contributors:
+ * Berlin Institute of Technology - Initial API and implementation
+ **********************************************************************/
+package org.objectteams;
+
+import java.util.HashSet;
+import java.util.WeakHashMap;
+
+
+/**
+ * This class is for internal use, only.
+ *
+ * Maintain information about existing threads as to manage
+ * team activation per thread vs. globally.
+ *
+ * @author Chistine Hundt
+ * @author Stephan Herrmann
+ */
+public class TeamThreadManager {
+
+ private static Object token = new Object();
+
+ private static HashSet<ITeam> globalActiveTeams = new HashSet<ITeam>();
+ private static WeakHashMap<ITeam,Object> teamsWithActivationInheritance = new WeakHashMap<ITeam,Object>();
+ private static HashSet<Thread> existingThreads = new HashSet<Thread>();
+
+ public static boolean newThreadStarted(boolean isMain, Thread parent) {
+ Thread currentThread = Thread.currentThread();
+ // already registered?
+ if (existingThreads.contains(currentThread))
+ return false;
+ // workaround for application hang on Mac OS with Apple JVM:
+ if (System.getProperty("os.name").startsWith("Mac"))
+ if (currentThread.getName().equals("AWT-Shutdown"))
+ return false;
+
+ ITeam[] globalTeams;
+ ITeam[] inheritableTeams;
+ synchronized (TeamThreadManager.class) {
+ boolean isFirst = existingThreads.isEmpty();
+ existingThreads.add(currentThread);
+ if (isMain || isFirst) {
+ for (Thread thread : fetchSystemThreads(currentThread))
+ if (thread != null)
+ existingThreads.add(thread);
+ }
+
+ globalTeams = globalActiveTeams.toArray(new ITeam[globalActiveTeams.size()]);
+ inheritableTeams = teamsWithActivationInheritance.keySet().toArray(new ITeam[teamsWithActivationInheritance.size()]);
+ }
+ // activate teams outside synchronized block:
+ for (ITeam t : globalTeams)
+ t.activate(currentThread); // small version? global -> already registered...!
+ if (parent != null)
+ for (ITeam t : inheritableTeams)
+ if (t.internalIsActiveSpecificallyFor(parent))
+ t.activate(currentThread); // pass activation from parent to child thread
+ return true;
+ }
+
+ /* Fetch all existing threads existing at this point in time. Result array is padded with nulls. */
+ private static Thread[] fetchSystemThreads(Thread currentThread) {
+ ThreadGroup group = currentThread.getThreadGroup();
+ {
+ ThreadGroup parentGroup;
+ while ((parentGroup= group.getParent()) != null)
+ group = parentGroup;
+ }
+ int size = group.activeCount();
+ Thread[] allThreads;
+ do {
+ size += 2;
+ allThreads = new Thread[size];
+ } while (group.enumerate(allThreads) == size);
+ return allThreads;
+ }
+
+ public static void threadEnded() {
+ ITeam[] teamsToDeactivate = internalThreadEnded();
+ // + remove per thread activation:
+ for (ITeam t : teamsToDeactivate)
+ //t.deactivate(Thread.currentThread()); // small version?
+ t.deactivateForEndedThread(Thread.currentThread());
+ }
+ private synchronized static ITeam[] internalThreadEnded() {
+ existingThreads.remove(Thread.currentThread());
+ // fetch all global active teams for deactivation:
+ return globalActiveTeams.toArray(new ITeam[globalActiveTeams.size()]);
+ }
+
+ public synchronized static void addGlobalActiveTeam(ITeam t) {
+ globalActiveTeams.add(t);
+ }
+
+ public synchronized static void removeGlobalActiveTeam(ITeam t) {
+ globalActiveTeams.remove(t);
+ }
+
+ public static HashSet<Thread> getExistingThreads() {
+ return existingThreads;
+ }
+ public static void registerTeamForActivationInheritance(ITeam aTeam) {
+ teamsWithActivationInheritance.put(aTeam,token);
+ }
+ public static void unRegisterTeamForActivationInheritance(ITeam aTeam) {
+ teamsWithActivationInheritance.remove(aTeam);
+ }
+
+}

Back to the top