/******************************************************************************* * Copyright (c) 2006, 2010 Wind River Systems 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: * Wind River Systems - initial API and implementation * Ericsson - Modified for multi threaded functionality * Patrick Chuong (Texas Instruments) - Add support for icon overlay in the debug view (Bug 334566) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.launch; import java.util.Map; import org.eclipse.cdt.debug.internal.ui.pinclone.PinCloneUtils; import org.eclipse.cdt.debug.ui.IPinProvider.IPinElementColorDescriptor; import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants; import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor; import org.eclipse.cdt.dsf.datamodel.IDMContext; import org.eclipse.cdt.dsf.debug.service.IProcesses; import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext; import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMData; import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.AbstractThreadVMNode; import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.ExecutionContextLabelText; import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.ILaunchVMConstants; import org.eclipse.cdt.dsf.gdb.internal.ui.GdbPinProvider; import org.eclipse.cdt.dsf.gdb.service.IGDBProcesses.IGdbThreadDMData; import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin; import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext; import org.eclipse.cdt.dsf.service.DsfSession; import org.eclipse.cdt.dsf.ui.concurrent.ViewerCountingRequestMonitor; import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor; import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate; import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelAttribute; import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelColumnInfo; import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelImage; import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelText; import org.eclipse.cdt.dsf.ui.viewmodel.properties.PropertiesBasedLabelProvider; import org.eclipse.cdt.dsf.ui.viewmodel.properties.VMDelegatingPropertiesUpdate; import org.eclipse.cdt.ui.CDTSharedImages; import org.eclipse.core.runtime.IStatus; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider; import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.ui.IMemento; @SuppressWarnings("restriction") public class ThreadVMNode extends AbstractThreadVMNode implements IElementLabelProvider, IElementMementoProvider { public ThreadVMNode(AbstractDMVMProvider provider, DsfSession session) { super(provider, session); } @Override public String toString() { return "ThreadVMNode(" + getSession().getId() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ } @Override protected IElementLabelProvider createLabelProvider() { PropertiesBasedLabelProvider provider = new PropertiesBasedLabelProvider(); provider.setColumnInfo( PropertiesBasedLabelProvider.ID_COLUMN_NO_COLUMNS, new LabelColumnInfo(new LabelAttribute[] { // Text is made of the thread name followed by its state and state change reason. new GdbExecutionContextLabelText( MessagesForGdbLaunchVM.ThreadVMNode_No_columns__text_format, new String[] { ExecutionContextLabelText.PROP_NAME_KNOWN, PROP_NAME, ExecutionContextLabelText.PROP_ID_KNOWN, ILaunchVMConstants.PROP_ID, IGdbLaunchVMConstants.PROP_OS_ID_KNOWN, IGdbLaunchVMConstants.PROP_OS_ID, IGdbLaunchVMConstants.PROP_CORES_ID_KNOWN, IGdbLaunchVMConstants.PROP_CORES_ID, ILaunchVMConstants.PROP_IS_SUSPENDED, ExecutionContextLabelText.PROP_STATE_CHANGE_REASON_KNOWN, ILaunchVMConstants.PROP_STATE_CHANGE_REASON, ExecutionContextLabelText.PROP_STATE_CHANGE_DETAILS_KNOWN, ILaunchVMConstants.PROP_STATE_CHANGE_DETAILS}), new LabelText(MessagesForGdbLaunchVM.ThreadVMNode_No_columns__Error__label, new String[0]), /* RUNNING THREAD - RED PIN */ new LabelImage(CDTSharedImages.getImageDescriptor(CDTSharedImages.IMG_THREAD_RUNNING_R_PINNED)) { { setPropertyNames(new String[] { ILaunchVMConstants.PROP_IS_SUSPENDED, IGdbLaunchVMConstants.PROP_PINNED_CONTEXT, IGdbLaunchVMConstants.PROP_PIN_COLOR }); } @Override public boolean isEnabled(IStatus status, Map<String, Object> properties) { Boolean prop = (Boolean) properties.get(ILaunchVMConstants.PROP_IS_SUSPENDED); Boolean pin_prop = (Boolean) properties.get(IGdbLaunchVMConstants.PROP_PINNED_CONTEXT); Object pin_color_prop = properties.get(IGdbLaunchVMConstants.PROP_PIN_COLOR); return (prop != null && pin_prop != null && pin_color_prop != null) ? !prop.booleanValue() && pin_prop.booleanValue() && pin_color_prop.equals(IPinElementColorDescriptor.RED) : false; }; }, /* RUNNING THREAD - GREEN PIN */ new LabelImage(CDTSharedImages.getImageDescriptor(CDTSharedImages.IMG_THREAD_RUNNING_G_PINNED)) { { setPropertyNames(new String[] { ILaunchVMConstants.PROP_IS_SUSPENDED, IGdbLaunchVMConstants.PROP_PINNED_CONTEXT, IGdbLaunchVMConstants.PROP_PIN_COLOR }); } @Override public boolean isEnabled(IStatus status, Map<String, Object> properties) { Boolean prop = (Boolean) properties.get(ILaunchVMConstants.PROP_IS_SUSPENDED); Boolean pin_prop = (Boolean) properties.get(IGdbLaunchVMConstants.PROP_PINNED_CONTEXT); Object pin_color_prop = properties.get(IGdbLaunchVMConstants.PROP_PIN_COLOR); return (prop != null && pin_prop != null && pin_color_prop != null) ? !prop.booleanValue() && pin_prop.booleanValue() && pin_color_prop.equals(IPinElementColorDescriptor.GREEN) : false; }; }, /* RUNNING THREAD - BLUE PIN */ new LabelImage(CDTSharedImages.getImageDescriptor(CDTSharedImages.IMG_THREAD_RUNNING_B_PINNED)) { { setPropertyNames(new String[] { ILaunchVMConstants.PROP_IS_SUSPENDED, IGdbLaunchVMConstants.PROP_PINNED_CONTEXT, IGdbLaunchVMConstants.PROP_PIN_COLOR }); } @Override public boolean isEnabled(IStatus status, Map<String, Object> properties) { Boolean prop = (Boolean) properties.get(ILaunchVMConstants.PROP_IS_SUSPENDED); Boolean pin_prop = (Boolean) properties.get(IGdbLaunchVMConstants.PROP_PINNED_CONTEXT); Object pin_color_prop = properties.get(IGdbLaunchVMConstants.PROP_PIN_COLOR); return (prop != null && pin_prop != null && pin_color_prop != null) ? !prop.booleanValue() && pin_prop.booleanValue() && pin_color_prop.equals(IPinElementColorDescriptor.BLUE) : false; }; }, /* RUNNING THREAD - NO PIN */ new LabelImage(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_THREAD_RUNNING)) { { setPropertyNames(new String[] { ILaunchVMConstants.PROP_IS_SUSPENDED }); } @Override public boolean isEnabled(IStatus status, java.util.Map<String,Object> properties) { // prop has been seen to be null during session shutdown [313823] Boolean prop = (Boolean)properties.get(ILaunchVMConstants.PROP_IS_SUSPENDED); return (prop != null) ? !prop.booleanValue() : false; }; }, /* SUSPENDED THREAD - RED PIN */ new LabelImage(CDTSharedImages.getImageDescriptor(CDTSharedImages.IMG_THREAD_SUSPENDED_R_PINNED)) { { setPropertyNames(new String[] { IGdbLaunchVMConstants.PROP_PINNED_CONTEXT, IGdbLaunchVMConstants.PROP_PIN_COLOR }); } @Override public boolean isEnabled(IStatus status, Map<String, Object> properties) { Boolean pin_prop = (Boolean)properties.get(IGdbLaunchVMConstants.PROP_PINNED_CONTEXT); Object pin_color_prop = properties.get(IGdbLaunchVMConstants.PROP_PIN_COLOR); return (pin_prop != null && pin_color_prop != null) ? pin_prop.booleanValue() && pin_color_prop.equals(IPinElementColorDescriptor.RED) : false; }; }, /* SUSPENDED THREAD - GREEN PIN */ new LabelImage(CDTSharedImages.getImageDescriptor(CDTSharedImages.IMG_THREAD_SUSPENDED_G_PINNED)) { { setPropertyNames(new String[] { IGdbLaunchVMConstants.PROP_PINNED_CONTEXT, IGdbLaunchVMConstants.PROP_PIN_COLOR }); } @Override public boolean isEnabled(IStatus status, Map<String, Object> properties) { Boolean pin_prop = (Boolean)properties.get(IGdbLaunchVMConstants.PROP_PINNED_CONTEXT); Object pin_color_prop = properties.get(IGdbLaunchVMConstants.PROP_PIN_COLOR); return (pin_prop != null && pin_color_prop != null) ? pin_prop.booleanValue() && pin_color_prop.equals(IPinElementColorDescriptor.GREEN) : false; }; }, /* SUSPENDED THREAD - BLUE PIN */ new LabelImage(CDTSharedImages.getImageDescriptor(CDTSharedImages.IMG_THREAD_SUSPENDED_B_PINNED)) { { setPropertyNames(new String[] { IGdbLaunchVMConstants.PROP_PINNED_CONTEXT, IGdbLaunchVMConstants.PROP_PIN_COLOR }); } @Override public boolean isEnabled(IStatus status, Map<String, Object> properties) { Boolean pin_prop = (Boolean)properties.get(IGdbLaunchVMConstants.PROP_PINNED_CONTEXT); Object pin_color_prop = properties.get(IGdbLaunchVMConstants.PROP_PIN_COLOR); return (pin_prop != null && pin_color_prop != null) ? pin_prop.booleanValue() && pin_color_prop.equals(IPinElementColorDescriptor.BLUE) : false; }; }, /* SUSPENDED THREAD - NO PIN */ new LabelImage(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED)), })); return provider; } @Override protected void updatePropertiesInSessionThread(IPropertiesUpdate[] updates) { IPropertiesUpdate[] parentUpdates = new IPropertiesUpdate[updates.length]; for (int i = 0; i < updates.length; i++) { final IPropertiesUpdate update = updates[i]; final ViewerCountingRequestMonitor countringRm = new ViewerCountingRequestMonitor(ImmediateExecutor.getInstance(), updates[i]); int count = 0; // Create a delegating update which will let the super-class fill in the // standard container properties. parentUpdates[i] = new VMDelegatingPropertiesUpdate(updates[i], countringRm); count++; IMIExecutionDMContext execDmc = findDmcInPath( update.getViewerInput(), update.getElementPath(), IMIExecutionDMContext.class); if (execDmc != null) { update.setProperty(ILaunchVMConstants.PROP_ID, Integer.toString(execDmc.getThreadId())); // set pin properties IPinElementColorDescriptor colorDesc = PinCloneUtils.getPinElementColorDescriptor(GdbPinProvider.getPinnedHandles(), execDmc); updates[i].setProperty(IGdbLaunchVMConstants.PROP_PIN_COLOR, colorDesc != null ? colorDesc.getOverlayColor() : null); updates[i].setProperty(IGdbLaunchVMConstants.PROP_PINNED_CONTEXT, PinCloneUtils.isPinnedTo(GdbPinProvider.getPinnedHandles(), execDmc)); } if (update.getProperties().contains(PROP_NAME) || update.getProperties().contains(IGdbLaunchVMConstants.PROP_OS_ID) || update.getProperties().contains(IGdbLaunchVMConstants.PROP_CORES_ID)) { IProcesses processService = getServicesTracker().getService(IProcesses.class); final IThreadDMContext threadDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IThreadDMContext.class); if (processService == null || threadDmc == null) { update.setStatus(DsfUIPlugin.newErrorStatus(IDsfStatusConstants.INVALID_HANDLE, "Service or handle invalid", null)); //$NON-NLS-1$ } else { processService.getExecutionData( threadDmc, new ViewerDataRequestMonitor<IThreadDMData>(getExecutor(), update) { @Override public void handleCompleted() { if (isSuccess()) { fillThreadDataProperties(update, getData()); } update.setStatus(getStatus()); countringRm.done(); } }); count++; } } countringRm.setDoneCount(count); } super.updatePropertiesInSessionThread(parentUpdates); } protected void fillThreadDataProperties(IPropertiesUpdate update, IThreadDMData data) { if (data.getName() != null && data.getName().length() > 0) { update.setProperty(PROP_NAME, data.getName()); } update.setProperty(IGdbLaunchVMConstants.PROP_OS_ID, data.getId()); if (data instanceof IGdbThreadDMData) { String[] cores = ((IGdbThreadDMData)data).getCores(); if (cores != null) { StringBuffer str = new StringBuffer(); for (String core : cores) { str.append(core + ","); //$NON-NLS-1$ } if (str.length() > 0) { String coresStr = str.substring(0, str.length() - 1); update.setProperty(IGdbLaunchVMConstants.PROP_CORES_ID, coresStr); } } } } private String produceThreadElementName(String viewName, IMIExecutionDMContext execCtx) { return "Thread." + execCtx.getThreadId(); //$NON-NLS-1$ } private static final String MEMENTO_NAME = "THREAD_MEMENTO_NAME"; //$NON-NLS-1$ /* * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider#compareElements(org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest[]) */ public void compareElements(IElementCompareRequest[] requests) { for ( IElementCompareRequest request : requests ) { Object element = request.getElement(); IMemento memento = request.getMemento(); String mementoName = memento.getString(MEMENTO_NAME); if (mementoName != null) { if (element instanceof IDMVMContext) { IDMContext dmc = ((IDMVMContext)element).getDMContext(); if ( dmc instanceof IMIExecutionDMContext) { String elementName = produceThreadElementName( request.getPresentationContext().getId(), (IMIExecutionDMContext) dmc ); request.setEqual( elementName.equals( mementoName ) ); } } } request.done(); } } /* * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider#encodeElements(org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest[]) */ public void encodeElements(IElementMementoRequest[] requests) { for ( IElementMementoRequest request : requests ) { Object element = request.getElement(); IMemento memento = request.getMemento(); if (element instanceof IDMVMContext) { IDMContext dmc = ((IDMVMContext)element).getDMContext(); if ( dmc instanceof IMIExecutionDMContext) { String elementName = produceThreadElementName( request.getPresentationContext().getId(), (IMIExecutionDMContext) dmc ); memento.putString(MEMENTO_NAME, elementName); } } request.done(); } } }