diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/DefaultDsfExecutor.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/DefaultDsfExecutor.java index af17457c8e3..6cef2c567f8 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/DefaultDsfExecutor.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/DefaultDsfExecutor.java @@ -14,6 +14,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintStream; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.Future; @@ -49,11 +50,6 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor */ private String fName; - /** - * Instance number of this executor, used with the executor name. - */ - private int fInstanceNumber; - /** Thread factory that creates the single thread to be used for this executor */ static class DsfThreadFactory implements ThreadFactory { private String fThreadName; @@ -78,9 +74,8 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor * @param name Name used to create executor's thread. */ public DefaultDsfExecutor(String name) { - super(1, new DsfThreadFactory(name + " - " + fgInstanceCounter)); //$NON-NLS-1$ + super(1, new DsfThreadFactory(name + " - " + fgInstanceCounter++)); //$NON-NLS-1$ fName = name; - fInstanceNumber = fgInstanceCounter++; if(DEBUG_EXECUTOR || ASSERTIONS_ENABLED) { // If tracing, pre-start the dispatch thread, and add it to the map. @@ -226,16 +221,13 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor traceBuilder.append(' '); // Record the executor # - traceBuilder.append('#'); + traceBuilder.append("DSF execution #"); //$NON-NLS-1$ traceBuilder.append(fSequenceNumber); // Record the executor name - traceBuilder.append('('); - traceBuilder.append(fName); - traceBuilder.append(" - "); //$NON-NLS-1$ - traceBuilder.append(fInstanceNumber); + traceBuilder.append(". Executor is ("); //$NON-NLS-1$ + traceBuilder.append(((DsfThreadFactory)getThreadFactory()).fThreadName); traceBuilder.append(')'); - traceBuilder.append(' '); // This will be a Runnable or a Callable. Hopefully it will also // be a DsfExecutable and thus be instrumented with trace/debug @@ -245,12 +237,20 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor // Append executable class name. The anonymous inner class name // name won't be very interesting; use the parent class instead. + traceBuilder.append("\n\tExecutable detail: \n\t\ttype = "); //$NON-NLS-1$ Class execClass = executable.getClass(); traceBuilder.append(execClass.isAnonymousClass() ? execClass.getSuperclass().getName() : execClass.getName()); - // Add executable's toString(). - traceBuilder.append("\n "); //$NON-NLS-1$ - traceBuilder.append(LoggingUtils.toString(executable, false)); + // Append the executable reference + final String refstr = LoggingUtils.toString(executable, false); + String tostr = LoggingUtils.trimTrailingNewlines(executable.toString()); + traceBuilder.append("\n\t\t"); //$NON-NLS-1$ + traceBuilder.append("instance = " + refstr); //$NON-NLS-1$ + if (!tostr.equals(refstr)) { + traceBuilder.append(" ["); //$NON-NLS-1$ + traceBuilder.append(tostr); + traceBuilder.append(']'); + } // Determine if the created-at and submitted-at information is // the same. If so, consolidate. @@ -281,16 +281,15 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor } if (canConsolidate) { - traceBuilder.append("\n created and submitted"); //$NON-NLS-1$ + traceBuilder.append("\n\t\tcreated and submitted"); //$NON-NLS-1$ if (createdBySeqNum != Integer.MIN_VALUE) { traceBuilder.append(" by #"); //$NON-NLS-1$ traceBuilder.append(createdBySeqNum); } if (createdAtStack != null) { - traceBuilder.append("\n at "); //$NON-NLS-1$ - traceBuilder.append(createdAtStack[0].toString()); - for (int i = 1; i < createdAtStack.length && i < 3; i++) { - traceBuilder.append("\n "); //$NON-NLS-1$ + traceBuilder.append(" at:"); //$NON-NLS-1$ + for (int i = 0; i < createdAtStack.length && i < 3; i++) { + traceBuilder.append("\n\t\t\t"); //$NON-NLS-1$ traceBuilder.append(createdAtStack[i].toString()); } } @@ -298,31 +297,29 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor else { // Append "create by" info. if (createdAtStack != null || createdBySeqNum != Integer.MIN_VALUE) { - traceBuilder.append("\n created "); //$NON-NLS-1$ + traceBuilder.append("\n\t\tcreated "); //$NON-NLS-1$ if (createdBySeqNum != Integer.MIN_VALUE) { traceBuilder.append(" by #"); //$NON-NLS-1$ traceBuilder.append(createdBySeqNum); } if (createdAtStack != null) { - traceBuilder.append("\n at "); //$NON-NLS-1$ - traceBuilder.append(createdAtStack[0].toString()); - for (int i = 1; i < createdAtStack.length && i < 3; i++) { - traceBuilder.append("\n "); //$NON-NLS-1$ + traceBuilder.append(" at:"); //$NON-NLS-1$ + for (int i = 0; i < createdAtStack.length && i < 3; i++) { + traceBuilder.append("\n\t\t\t"); //$NON-NLS-1$ traceBuilder.append(createdAtStack[i].toString()); } } } // Submitted info - traceBuilder.append("\n submitted"); //$NON-NLS-1$ + traceBuilder.append("\n\t\tsubmitted"); //$NON-NLS-1$ if (fSubmittedBy != null) { traceBuilder.append(" by #"); //$NON-NLS-1$ traceBuilder.append(fSubmittedBy.fSequenceNumber); } - traceBuilder.append("\n at "); //$NON-NLS-1$ - traceBuilder.append(fSubmittedAt.fStackTraceElements[0].toString()); - for (int i = 1; i < fSubmittedAt.fStackTraceElements.length && i < 3; i++) { - traceBuilder.append("\n "); //$NON-NLS-1$ + traceBuilder.append(" at:"); //$NON-NLS-1$ + for (int i = 0; i < fSubmittedAt.fStackTraceElements.length && i < 3; i++) { + traceBuilder.append("\n\t\t\t"); //$NON-NLS-1$ traceBuilder.append(fSubmittedAt.fStackTraceElements[i].toString()); } } @@ -469,4 +466,22 @@ public class DefaultDsfExecutor extends ScheduledThreadPoolExecutor } return super.submit(command, result); } + + @Override + public void shutdown() { + if (DEBUG_EXECUTOR && ("".equals(DEBUG_EXECUTOR_NAME) || fName.equals(DEBUG_EXECUTOR_NAME))) { //$NON-NLS-1$ + DsfPlugin.debug(DsfPlugin.getDebugTime() + " Executor (" + ((DsfThreadFactory)getThreadFactory()).fThreadName + ") is being shut down. Already submitted tasks will be executed, new ones will not."); //$NON-NLS-1$ //$NON-NLS-2$ + } + super.shutdown(); + } + + @Override + public List shutdownNow() { + if (DEBUG_EXECUTOR && ("".equals(DEBUG_EXECUTOR_NAME) || fName.equals(DEBUG_EXECUTOR_NAME))) { //$NON-NLS-1$ + DsfPlugin.debug(DsfPlugin.getDebugTime() + " Executor (" + ((DsfThreadFactory)getThreadFactory()).fThreadName + ") is being shut down. No queued or new tasks will be executed, and will attempt to cancel active ones."); //$NON-NLS-1$ //$NON-NLS-2$ + } + return super.shutdownNow(); + } + + } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/DsfExecutable.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/DsfExecutable.java index 902007ee875..7fc094fc9c0 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/DsfExecutable.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/DsfExecutable.java @@ -14,6 +14,7 @@ import java.util.HashSet; import java.util.Set; import org.eclipse.cdt.dsf.internal.DsfPlugin; +import org.eclipse.cdt.dsf.internal.LoggingUtils; import org.eclipse.core.runtime.Platform; /** @@ -179,10 +180,15 @@ public class DsfExecutable { traceBuilder.append(DsfPlugin.getDebugTime()); traceBuilder.append(' '); - // Record the event - traceBuilder.append("DsfExecutable was never executed:\n "); //$NON-NLS-1$ - traceBuilder.append(this); - traceBuilder.append("\nCreated at:"); //$NON-NLS-1$ + final String refstr = LoggingUtils.toString(this, false); + traceBuilder.append("DSF executable was never executed: " + refstr); //$NON-NLS-1$ + final String tostr = LoggingUtils.trimTrailingNewlines(this.toString()); + if (!tostr.equals(refstr)) { + traceBuilder.append(" ["); //$NON-NLS-1$ + traceBuilder.append(tostr); + traceBuilder.append(']'); + } + traceBuilder.append("\nCreated at:\n"); //$NON-NLS-1$ traceBuilder.append(fCreatedAt); DsfPlugin.debug(traceBuilder.toString()); diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/StackTraceWrapper.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/StackTraceWrapper.java index fe473549b9d..f0c0a4e1719 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/StackTraceWrapper.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/concurrent/StackTraceWrapper.java @@ -25,10 +25,23 @@ class StackTraceWrapper { @Override public String toString() { + final int MAX_FRAMES = 10; + final int count = Math.min(fStackTraceElements.length, MAX_FRAMES); StringBuilder builder = new StringBuilder(fStackTraceElements.length * 30); - for (int i = 0; i < fStackTraceElements.length && i < 10; i++) { + int i = 0; + while (true) { + builder.append('\t'); builder.append(fStackTraceElements[i]); - if (i < fStackTraceElements.length && i < 10) builder.append("\n at "); //$NON-NLS-1$ + if (++i == count) { + // last iteration + if (fStackTraceElements.length > count) { + builder.append("\n\t..."); //$NON-NLS-1$ + } + break; + } + else { + builder.append('\n'); + } } return builder.toString(); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/internal/LoggingUtils.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/internal/LoggingUtils.java index 343458d5eda..e0da4f3958c 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/internal/LoggingUtils.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/internal/LoggingUtils.java @@ -82,5 +82,25 @@ public class LoggingUtils { return str.toString(); } - + /** + * General string utility for removing newline and space character from the + * end of a string. Typically used when logging an object's toString() + * + * @param str + * the string + * @return the string without trailing newlines + */ + public static String trimTrailingNewlines(String str) { + final int strlen = str.length(); + if (strlen == 0) { + return str; + } + + int removeCount = 0; + for (int i = strlen - 1; i >= 0 && Character.isWhitespace(str.charAt(i)); i--) { + removeCount++; + } + + return (removeCount == 0) ? str : str.substring(0, str.length() - removeCount); + } }