diff options
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.java | 121 |
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); + } + +} |