From 2f1d6c7f949a41fe025bdf8c7fc80080d3974e4d Mon Sep 17 00:00:00 2001 From: Mikhail Khodjaiants Date: Thu, 29 Jan 2004 20:11:23 +0000 Subject: [PATCH] Fire sets of debug events instead of firing it one by one. --- debug/org.eclipse.cdt.debug.core/ChangeLog | 7 +- .../internal/core/model/CDebugTarget.java | 216 +++++++++++++----- .../debug/internal/core/model/CThread.java | 91 ++++++-- 3 files changed, 238 insertions(+), 76 deletions(-) diff --git a/debug/org.eclipse.cdt.debug.core/ChangeLog b/debug/org.eclipse.cdt.debug.core/ChangeLog index ddf440baea7..456fe9d2181 100644 --- a/debug/org.eclipse.cdt.debug.core/ChangeLog +++ b/debug/org.eclipse.cdt.debug.core/ChangeLog @@ -1,6 +1,11 @@ +2004-01-29 Mikhail Khodjaiants + Fire sets of debug events instead of firing it one by one. + * CDebugTarget.java + * CThread.java + 2004-01-29 Mikhail Khodjaiants Added DebugEvent factory methods to 'CDebugElement'. - CDebugElement.java + * CDebugElement.java 2004-01-15 Mikhail Khodjaiants Fix for bug 48682: IThread.getBreakpoints() stubbed out. diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CDebugTarget.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CDebugTarget.java index a5243a9fc79..e412bea291e 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CDebugTarget.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CDebugTarget.java @@ -137,6 +137,8 @@ public class CDebugTarget extends CDebugElement } } + private boolean fSuspending; + /** * The type of this target. */ @@ -346,6 +348,16 @@ public class CDebugTarget extends CDebugElement } for ( int i = 0; i < threads.length; ++i ) createThread( threads[i] ); + + // Fire thread creation events. + List list = getThreadList(); + ArrayList debugEvents = new ArrayList( list.size() ); + Iterator it = list.iterator(); + while( it.hasNext() ) + { + debugEvents.add( ((CThread)it.next()).createCreateEvent() ); + } + fireEventSet( (DebugEvent[])debugEvents.toArray( new DebugEvent[debugEvents.size()] ) ); } /** @@ -526,16 +538,34 @@ public class CDebugTarget extends CDebugElement */ public void terminate() throws DebugException { - try + if ( isTerminating() ) { - setTerminating( true ); - getCDITarget().terminate(); - } - catch( CDIException e ) - { - setTerminating( false ); - targetRequestFailed( e.getMessage(), e ); + return; } + setTerminating( true ); + DebugPlugin.getDefault().asyncExec( + new Runnable() + { + public void run() + { + try + { + getCDITarget().terminate(); + } + catch( CDIException e ) + { + setTerminating( false ); + try + { + targetRequestFailed( e.getMessage(), e ); + } + catch( DebugException e1 ) + { + CDebugUtils.error( e1.getStatus(), CDebugTarget.this ); + } + } + } + } ); } /** @@ -593,7 +623,7 @@ public class CDebugTarget extends CDebugElement */ public void resume() throws DebugException { - if ( !isSuspended() ) + if ( !isSuspended() && !isSuspending() ) return; try { @@ -610,18 +640,41 @@ public class CDebugTarget extends CDebugElement */ public void suspend() throws DebugException { - if ( isSuspended() ) + if ( isSuspended() || isSuspending() ) return; - try - { - getCDITarget().suspend(); - } - catch( CDIException e ) - { - targetRequestFailed( e.getMessage(), e ); - } + + setSuspending(true); + DebugPlugin.getDefault().asyncExec(new Runnable() { + /* (non-Javadoc) + * @see java.lang.Runnable#run() + */ + public void run() { + try { + getCDITarget().suspend(); + } catch( CDIException e ) { + try { + targetRequestFailed( e.getMessage(), e ); + } catch (DebugException e1) { + CDebugUtils.error(e1.getStatus(), CDebugTarget.this); + } + + } finally { + setSuspending(false); + } + } + }); } + protected void setSuspending( boolean value ) + { + fSuspending = value; + } + + protected boolean isSuspending() + { + return fSuspending; + } + /** * Notifies threads that they have been suspended. * @@ -641,42 +694,50 @@ public class CDebugTarget extends CDebugElement */ protected synchronized List refreshThreads() { - ArrayList list = new ArrayList( 5 ); ArrayList newThreads = new ArrayList( 5 ); + ArrayList list = new ArrayList( 5 ); + ArrayList debugEvents = new ArrayList( 5 ); + List oldList = (List)getThreadList().clone(); + + ICDIThread[] cdiThreads = new ICDIThread[0]; try { - ICDIThread[] cdiThreads = getCDITarget().getThreads(); - for ( int i = 0; i < cdiThreads.length; ++i ) - { - CThread thread = findThread( cdiThreads[i] ); - if ( thread == null ) - { - thread = new CThread( this, cdiThreads[i] ); - newThreads.add( thread ); - } - else - { - getThreadList().remove( thread ); - } - list.add( thread ); - } - Iterator it = getThreadList().iterator(); - while( it.hasNext() ) - { - ((CThread)it.next()).terminated(); - } - getThreadList().clear(); - setThreadList( list ); - it = newThreads.iterator(); - while( it.hasNext() ) - { - ((CThread)it.next()).fireCreationEvent(); - } + cdiThreads = getCDITarget().getThreads(); } catch( CDIException e ) { CDebugCorePlugin.log( e ); } + for ( int i = 0; i < cdiThreads.length; ++i ) + { + CThread thread = findThread( oldList, cdiThreads[i] ); + if ( thread == null ) + { + thread = new CThread( this, cdiThreads[i] ); + newThreads.add( thread ); + } + else + { + oldList.remove( thread ); + } + list.add( thread ); + } + + Iterator it = oldList.iterator(); + while( it.hasNext() ) + { + CThread thread = (CThread)it.next(); + thread.terminated(); + debugEvents.add( thread.createTerminateEvent() ); + } + setThreadList( list ); + it = newThreads.iterator(); + while( it.hasNext() ) + { + debugEvents.add( ((CThread)it.next()).createCreateEvent() ); + } + if ( debugEvents.size() > 0 ) + fireEventSet( (DebugEvent[])debugEvents.toArray( new DebugEvent[debugEvents.size()] ) ); setCurrentThread(); return newThreads; } @@ -684,8 +745,13 @@ public class CDebugTarget extends CDebugElement /** * Notifies threads that they have been resumed */ - protected void resumeThreads( ICDIResumedEvent event ) + protected synchronized void resumeThreads( List debugEvents, int detail ) { + Iterator it = getThreadList().iterator(); + while( it.hasNext() ) + { + ((CThread)it.next()).resumed( detail, debugEvents ); + } } /* (non-Javadoc) @@ -1179,13 +1245,17 @@ public class CDebugTarget extends CDebugElement */ protected void removeAllThreads() { - Iterator itr = getThreadList().iterator(); + List threads = getThreadList(); setThreadList( new ArrayList( 0 ) ); - while( itr.hasNext() ) + ArrayList debugEvents = new ArrayList( threads.size() ); + Iterator it = threads.iterator(); + while( it.hasNext() ) { - CThread thread = (CThread)itr.next(); + CThread thread = (CThread)it.next(); thread.terminated(); + debugEvents.add( thread.createTerminateEvent() ); } + fireEventSet( (DebugEvent[])debugEvents.toArray( new DebugEvent[debugEvents.size()] ) ); } /** @@ -1218,7 +1288,6 @@ public class CDebugTarget extends CDebugElement { CThread thread = new CThread( this, cdiThread ); getThreadList().add( thread ); - thread.fireCreationEvent(); return thread; } @@ -1233,7 +1302,6 @@ public class CDebugTarget extends CDebugElement CThread thread = new CThread( this, cdiThread ); thread.setRunning( true ); getThreadList().add( thread ); - thread.fireCreationEvent(); return thread; } @@ -1249,7 +1317,6 @@ public class CDebugTarget extends CDebugElement if ( event.getSource() instanceof ICDITarget ) { suspendThreads( event ); - fireSuspendEvent( DebugEvent.UNSPECIFIED ); } // We need this for debuggers that don't have notifications // for newly created threads. @@ -1399,7 +1466,7 @@ public class CDebugTarget extends CDebugElement setCurrentStateId( IState.RUNNING ); setCurrentStateInfo( null ); resetStatus(); - resumeThreads( event ); + ArrayList debugEvents = new ArrayList( 10 ); int detail = DebugEvent.UNSPECIFIED; switch( event.getType() ) { @@ -1418,9 +1485,11 @@ public class CDebugTarget extends CDebugElement detail = DebugEvent.STEP_RETURN; break; } + resumeThreads( debugEvents, detail ); if ( getRunningInfo() == null ) setRunningInfo( event.getType() ); - fireResumeEvent( detail ); + debugEvents.add( createResumeEvent( detail ) ); + fireEventSet( (DebugEvent[])debugEvents.toArray( new DebugEvent[debugEvents.size()] ) ); } private void handleEndSteppingRange( ICDIEndSteppingRange endSteppingRange ) @@ -1526,10 +1595,11 @@ public class CDebugTarget extends CDebugElement { ICDIThread cdiThread = (ICDIThread)event.getSource(); CThread thread = findThread( cdiThread ); - if ( thread == null ) - { - createThread( cdiThread ); - } + if ( thread == null ) + { + thread = createThread( cdiThread ); + thread.fireCreationEvent(); + } } private void handleThreadTerminatedEvent( ICDIDestroyedEvent event ) @@ -1540,6 +1610,7 @@ public class CDebugTarget extends CDebugElement { getThreadList().remove( thread ); thread.terminated(); + thread.fireTerminateEvent(); } } @@ -1562,6 +1633,17 @@ public class CDebugTarget extends CDebugElement return null; } + public CThread findThread( List threads, ICDIThread cdiThread ) + { + for ( int i = 0; i < threads.size(); i++ ) + { + CThread t = (CThread)threads.get( i ); + if ( t.getCDIThread().equals( cdiThread ) ) + return t; + } + return null; + } + /* (non-Javadoc) * @see org.eclipse.cdt.debug.core.IState#getCurrentStateId() */ @@ -2286,4 +2368,20 @@ public class CDebugTarget extends CDebugElement } return (IBreakpoint[])list.toArray( new IBreakpoint[list.size()]); } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() + { + String result = ""; + try + { + result = getName(); + } + catch( DebugException e ) + { + } + return result; + } } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CThread.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CThread.java index 373aaaf1750..5f0f3221764 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CThread.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CThread.java @@ -11,6 +11,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; +import org.eclipse.cdt.debug.core.CDebugUtils; import org.eclipse.cdt.debug.core.cdi.CDIException; import org.eclipse.cdt.debug.core.cdi.ICDIConfiguration; import org.eclipse.cdt.debug.core.cdi.ICDIEndSteppingRange; @@ -40,6 +41,7 @@ import org.eclipse.cdt.debug.core.sourcelookup.ISourceMode; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.model.IBreakpoint; import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.core.model.IThread; @@ -59,6 +61,8 @@ public class CThread extends CDebugElement ISwitchToFrame, ICDIEventListener { + private boolean fSuspending; + private final static int MAX_STACK_DEPTH = 100; /** @@ -435,8 +439,7 @@ public class CThread extends CDebugElement } else if ( event instanceof ICDIResumedEvent ) { - if ( ( source instanceof ICDIThread && source.equals( getCDIThread() ) ) || - source instanceof ICDITarget ) + if ( ( source instanceof ICDIThread && source.equals( getCDIThread() ) ) ) { handleResumedEvent( (ICDIResumedEvent)event ); } @@ -494,7 +497,7 @@ public class CThread extends CDebugElement */ public void resume() throws DebugException { - if ( !isSuspended() ) + if ( !isSuspended() && !isSuspending() ) return; try { @@ -511,18 +514,39 @@ public class CThread extends CDebugElement */ public void suspend() throws DebugException { - if ( isSuspended() ) - { + if ( isSuspended() || isSuspending() ) return; - } - try - { - getCDIThread().suspend(); - } - catch( CDIException e ) - { - targetRequestFailed( e.getMessage(), e ); - } + + setSuspending(true); + DebugPlugin.getDefault().asyncExec(new Runnable() { + /* (non-Javadoc) + * @see java.lang.Runnable#run() + */ + public void run() { + try { + getCDITarget().suspend(); + } catch( CDIException e ) { + try { + targetRequestFailed( e.getMessage(), e ); + } catch (DebugException e1) { + CDebugUtils.error(e1.getStatus(), CThread.this); + } + + } finally { + setSuspending(false); + } + } + }); + } + + protected void setSuspending( boolean value ) + { + fSuspending = value; + } + + protected boolean isSuspending() + { + return fSuspending; } /* (non-Javadoc) @@ -771,7 +795,6 @@ public class CThread extends CDebugElement setRunning( false ); dispose(); cleanup(); - fireTerminateEvent(); } /* (non-Javadoc) @@ -865,7 +888,7 @@ public class CThread extends CDebugElement setRunning( false ); if ( event.getSource() instanceof ICDITarget ) { - if ( isCurrent() ) + if ( isCurrent() && getCurrentStateId() != IState.SUSPENDED ) { setCurrentStateId( IState.SUSPENDED ); ICDISessionObject reason = event.getReason(); @@ -1152,4 +1175,40 @@ public class CThread extends CDebugElement return result; } */ + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() + { + String result = ""; + try + { + result = getName(); + } + catch( DebugException e ) + { + } + return result; + } + + protected void resumed( int detail, List events ) + { + setRunning( true ); + setLastStackFrame( null ); + int state = IState.RUNNING; + if ( isCurrent() && detail != DebugEvent.CLIENT_REQUEST && detail != DebugEvent.UNSPECIFIED ) + { + preserveStackFrames(); + state = IState.STEPPING; + events.add( createResumeEvent( detail ) ); + } + else + { + disposeStackFrames(); + events.add( createChangeEvent( DebugEvent.CONTENT ) ); + } + setCurrentStateId( state ); + setCurrentStateInfo( null ); + } }