/**
* Copyright (C) 2014 Eric Van Dewoestine
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.eclim.plugin.jdt.command.debug.context;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.debug.core.DebugException;
import org.eclipse.jdt.debug.core.IJavaThread;
/**
* Maintains the state of all threads belonging to a debug session.
*/
public class ThreadContext
{
/**
* Thread that is being currently stepped through. There can be more than one
* thread suspended in some breakpoint ready to be stepped through. But only
* one of them can be stepped through at a time. This field holds that
* thread.
*/
private IJavaThread steppingThread = null;
private Map<Long, IJavaThread> threadMap =
new ConcurrentHashMap<Long, IJavaThread>();
public synchronized IJavaThread getSteppingThread()
{
if (steppingThread != null) {
// Check if it is still valid thread and in suspended state
if (steppingThread.isSuspended()) {
return steppingThread;
}
}
// Find the first suspended thread and set it as stepping thread
steppingThread = null;
for (Map.Entry<Long, IJavaThread> entry : threadMap.entrySet()) {
if (entry.getValue().isSuspended()) {
steppingThread = entry.getValue();
}
}
return steppingThread;
}
/**
* Explicitly sets the stepping thread.
*/
public synchronized void setSteppingThread(IJavaThread thread)
{
this.steppingThread = thread;
}
public Collection<IJavaThread> getThreads()
{
return threadMap.values();
}
public IJavaThread getThread(long threadId)
{
return threadMap.get(threadId);
}
public synchronized void update(IJavaThread thread)
throws DebugException
{
long threadId = thread.getThreadObject().getUniqueId();
threadMap.put(threadId, thread);
}
public synchronized void remove(IJavaThread thread)
throws DebugException
{
long threadId = thread.getThreadObject().getUniqueId();
threadMap.remove(threadId);
if (steppingThread != null &&
steppingThread.getThreadObject().getUniqueId() == threadId)
{
steppingThread = null;
}
}
/**
* Suspends the given thread.
*/
public void suspend(long threadId)
throws DebugException
{
IJavaThread thread = threadMap.get(threadId);
if (thread != null) {
thread.suspend();
}
}
/**
* Resumes execution of the given thread.
*/
public void resume(long threadId)
throws DebugException
{
IJavaThread thread = threadMap.get(threadId);
if (thread != null) {
thread.resume();
}
}
}