diff --git a/intrace.appengine/.classpath b/intrace.appengine/.classpath
index bea5790..9a9cdee 100644
--- a/intrace.appengine/.classpath
+++ b/intrace.appengine/.classpath
@@ -1,7 +1,7 @@
-
+
diff --git a/intrace.appengine/.project b/intrace.appengine/.project
index 255524a..19996dd 100644
--- a/intrace.appengine/.project
+++ b/intrace.appengine/.project
@@ -16,12 +16,12 @@
- com.google.appengine.eclipse.core.projectValidator
+ com.google.appengine.eclipse.core.enhancerbuilder
- com.google.appengine.eclipse.core.enhancerbuilder
+ com.google.appengine.eclipse.core.projectValidator
diff --git a/intrace.appengine/.settings/com.google.appengine.eclipse.core.prefs b/intrace.appengine/.settings/com.google.appengine.eclipse.core.prefs
index efbf0a4..1427f4f 100644
--- a/intrace.appengine/.settings/com.google.appengine.eclipse.core.prefs
+++ b/intrace.appengine/.settings/com.google.appengine.eclipse.core.prefs
@@ -1,3 +1,3 @@
-#Fri May 20 09:24:41 BST 2011
+#Mon Nov 07 21:54:15 GMT 2011
eclipse.preferences.version=1
-filesCopiedToWebInfLib=appengine-api-1.0-sdk-1.5.0.jar|appengine-api-labs-1.5.0.jar|appengine-jsr107cache-1.5.0.jar|jsr107cache-1.1.jar|datanucleus-appengine-1.0.8.final.jar|datanucleus-core-1.1.5.jar|datanucleus-jpa-1.1.5.jar|geronimo-jpa_3.0_spec-1.1.1.jar|geronimo-jta_1.1_spec-1.1.1.jar|jdo2-api-2.3-eb.jar
+filesCopiedToWebInfLib=
diff --git a/intrace.appengine/war/WEB-INF/lib/appengine-api-1.0-sdk-1.5.0.jar b/intrace.appengine/war/WEB-INF/lib/appengine-api-1.0-sdk-1.5.5.jar
similarity index 72%
rename from intrace.appengine/war/WEB-INF/lib/appengine-api-1.0-sdk-1.5.0.jar
rename to intrace.appengine/war/WEB-INF/lib/appengine-api-1.0-sdk-1.5.5.jar
index 1d1831d..db0f2cc 100644
Binary files a/intrace.appengine/war/WEB-INF/lib/appengine-api-1.0-sdk-1.5.0.jar and b/intrace.appengine/war/WEB-INF/lib/appengine-api-1.0-sdk-1.5.5.jar differ
diff --git a/intrace.appengine/war/WEB-INF/lib/appengine-api-labs-1.5.0.jar b/intrace.appengine/war/WEB-INF/lib/appengine-api-labs-1.5.5.jar
similarity index 62%
rename from intrace.appengine/war/WEB-INF/lib/appengine-api-labs-1.5.0.jar
rename to intrace.appengine/war/WEB-INF/lib/appengine-api-labs-1.5.5.jar
index 00f42c7..1af39ab 100644
Binary files a/intrace.appengine/war/WEB-INF/lib/appengine-api-labs-1.5.0.jar and b/intrace.appengine/war/WEB-INF/lib/appengine-api-labs-1.5.5.jar differ
diff --git a/intrace.appengine/war/WEB-INF/lib/appengine-jsr107cache-1.5.0.jar b/intrace.appengine/war/WEB-INF/lib/appengine-jsr107cache-1.5.0.jar
deleted file mode 100644
index 240e4d5..0000000
Binary files a/intrace.appengine/war/WEB-INF/lib/appengine-jsr107cache-1.5.0.jar and /dev/null differ
diff --git a/intrace.appengine/war/WEB-INF/lib/appengine-jsr107cache-1.5.5.jar b/intrace.appengine/war/WEB-INF/lib/appengine-jsr107cache-1.5.5.jar
new file mode 100644
index 0000000..fc7e9c0
Binary files /dev/null and b/intrace.appengine/war/WEB-INF/lib/appengine-jsr107cache-1.5.5.jar differ
diff --git a/intrace.appengine/war/WEB-INF/lib/datanucleus-appengine-1.0.8.final.jar b/intrace.appengine/war/WEB-INF/lib/datanucleus-appengine-1.0.8.final.jar
deleted file mode 100644
index 9edeee7..0000000
Binary files a/intrace.appengine/war/WEB-INF/lib/datanucleus-appengine-1.0.8.final.jar and /dev/null differ
diff --git a/intrace.appengine/war/WEB-INF/lib/datanucleus-appengine-1.0.9.final.jar b/intrace.appengine/war/WEB-INF/lib/datanucleus-appengine-1.0.9.final.jar
new file mode 100644
index 0000000..d8b7b96
Binary files /dev/null and b/intrace.appengine/war/WEB-INF/lib/datanucleus-appengine-1.0.9.final.jar differ
diff --git a/intrace.ecl.plugin/lib/intrace-agent.jar b/intrace.ecl.plugin/lib/intrace-agent.jar
index cd3b3e5..35f9dcf 100644
Binary files a/intrace.ecl.plugin/lib/intrace-agent.jar and b/intrace.ecl.plugin/lib/intrace-agent.jar differ
diff --git a/intrace.ecl.plugin/lib/intrace-ui-helper.jar b/intrace.ecl.plugin/lib/intrace-ui-helper.jar
index a0d88e3..435e736 100644
Binary files a/intrace.ecl.plugin/lib/intrace-ui-helper.jar and b/intrace.ecl.plugin/lib/intrace-ui-helper.jar differ
diff --git a/intrace.ecl.plugin/src/intrace/ecl/ui/launching/InTraceLaunchConfigTab.java b/intrace.ecl.plugin/src/intrace/ecl/ui/launching/InTraceLaunchConfigTab.java
new file mode 100644
index 0000000..89642a8
--- /dev/null
+++ b/intrace.ecl.plugin/src/intrace/ecl/ui/launching/InTraceLaunchConfigTab.java
@@ -0,0 +1,270 @@
+package intrace.ecl.ui.launching;
+
+import intrace.ecl.ui.output.InTraceEditor;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import net.miginfocom.swt.MigLayout;
+
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.ILaunchConfigurationDialog;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.intrace.client.gui.helper.ClientStrings;
+import org.intrace.client.gui.helper.InTraceUI;
+import org.intrace.client.gui.helper.TraceFilterThread;
+import org.intrace.client.gui.helper.InTraceUI.UIMode;
+import org.intrace.client.gui.helper.InTraceUI.UIModeData;
+import org.intrace.client.gui.helper.IncludeExcludeWindow;
+import org.intrace.client.gui.helper.IncludeExcludeWindow.PatternInputCallback;
+
+class InTraceLaunchConfigTab implements ILaunchConfigurationTab
+{
+ private Image icon16;
+ private Display display;
+ private Composite composite;
+ private Button classesButton;
+
+ private String classRegex = "";
+ private String classExcludeRegex = "";
+
+ private List includePattern = TraceFilterThread.MATCH_ALL;
+ private List excludePattern = TraceFilterThread.MATCH_NONE;
+
+ private Button textFilter;
+
+ @Override
+ public void createControl(Composite parent)
+ {
+ display = parent.getDisplay();
+ MigLayout tabLayout = new MigLayout("fill", "[]", "[][][grow]");
+
+ composite = new Composite(parent, SWT.NONE);
+ composite.setLayout(tabLayout);
+
+ classesButton = new Button(composite, SWT.PUSH);
+ classesButton.setText("Classes To Trace...");
+ classesButton.setLayoutData("growx,wrap");
+
+ final UIModeData modeData = InTraceEditor.getUIModeData();
+
+ classesButton
+ .addSelectionListener(new org.eclipse.swt.events.SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent arg0)
+ {
+ IncludeExcludeWindow regexInput = new IncludeExcludeWindow(
+ ClientStrings.CLASS_TITLE, ClientStrings.CLASS_HELP_TEXT, UIMode.ECLIPSE,
+ modeData,
+ new PatternInputCallback()
+ {
+ private List includePattern = null;
+ private List excludePattern = null;
+
+ @Override
+ public void setIncludePattern(List newIncludePattern)
+ {
+ includePattern = newIncludePattern;
+ savePatterns();
+ }
+
+ @Override
+ public void setExcludePattern(List newExcludePattern)
+ {
+ excludePattern = newExcludePattern;
+ savePatterns();
+ }
+
+ private void savePatterns()
+ {
+ if ((includePattern != null) && (excludePattern != null))
+ {
+ setRegex(InTraceUI.getStringFromList(includePattern),
+ InTraceUI.getStringFromList(excludePattern));
+ }
+ }
+ },
+ InTraceUI.getListFromString(classRegex),
+ InTraceUI.getListFromString(classExcludeRegex),
+ InTraceUI.ALLOW_CLASSES);
+ InTraceUI.placeDialogInCenter(display.getBounds(), regexInput.sWindow);
+ }
+ });
+
+ textFilter = new Button(composite, SWT.PUSH);
+ textFilter.setText("Trace Filters...");
+ textFilter.setLayoutData("growx");
+
+ final PatternInputCallback patternCallback = new PatternInputCallback()
+ {
+ @Override
+ public void setIncludePattern(List newIncludePattern)
+ {
+ includePattern = newIncludePattern;
+ savePatterns();
+ }
+
+ @Override
+ public void setExcludePattern(List newExcludePattern)
+ {
+ excludePattern = newExcludePattern;
+ savePatterns();
+ }
+
+ private void savePatterns()
+ {
+ if ((includePattern != null) && (excludePattern != null))
+ {
+ if (includePattern.equals(TraceFilterThread.MATCH_NONE) &&
+ excludePattern.equals(TraceFilterThread.MATCH_NONE))
+ {
+ includePattern = TraceFilterThread.MATCH_ALL;
+ }
+ applyPatterns(includePattern, excludePattern);
+ }
+ }
+ };
+
+ textFilter
+ .addSelectionListener(new org.eclipse.swt.events.SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent arg0)
+ {
+ IncludeExcludeWindow regexInput;
+ regexInput = new IncludeExcludeWindow("Output Filter", ClientStrings.FILTER_HELP_TEXT, UIMode.ECLIPSE,
+ modeData,
+ patternCallback,
+ includePattern,
+ excludePattern,
+ InTraceUI.ALLOW_ALL);
+ InTraceUI.placeDialogInCenter(display.getBounds(), regexInput.sWindow);
+ }
+ });
+ }
+
+ private void setRegex(String stringFromList,
+ String stringFromList2)
+ {
+ // TODO Auto-generated method stub
+ }
+
+ private void applyPatterns(List includePattern2,
+ List excludePattern2)
+ {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public Control getControl()
+ {
+ return composite;
+ }
+
+ @Override
+ public void setLaunchConfigurationDialog(ILaunchConfigurationDialog dialog)
+ {
+ // Do nothing
+ }
+
+ @Override
+ public void initializeFrom(ILaunchConfiguration configuration)
+ {
+ // Ignore
+ }
+
+ @Override
+ public void setDefaults(ILaunchConfigurationWorkingCopy configuration)
+ {
+ // Do nothing
+ }
+
+ @Override
+ public void dispose()
+ {
+ icon16.dispose();
+ }
+
+ @Override
+ public void performApply(ILaunchConfigurationWorkingCopy configuration)
+ {
+ // Ignore
+ }
+
+ @Override
+ public String getErrorMessage()
+ {
+ return null;
+ }
+
+ @Override
+ public String getMessage()
+ {
+ return null;
+ }
+
+ @Override
+ public boolean isValid(ILaunchConfiguration launchConfig)
+ {
+ return true;
+ }
+
+ @Override
+ public boolean canSave()
+ {
+ return false;
+ }
+
+ @Override
+ public void launched(ILaunch launch)
+ {
+ // Not called anymore
+ }
+
+ @Override
+ public String getName()
+ {
+ return "InTrace";
+ }
+
+ @Override
+ public Image getImage()
+ {
+ ClassLoader loader = InTraceLaunchConfigTab.class.getClassLoader();
+ InputStream is16 = loader.getResourceAsStream(
+ "org/intrace/icons/intrace16.gif");
+ icon16 = new Image(display, is16);
+ try
+ {
+ is16.close();
+ }
+ catch (IOException e)
+ {
+ // Ignore
+ }
+ return icon16;
+ }
+
+ @Override
+ public void activated(ILaunchConfigurationWorkingCopy workingCopy)
+ {
+ // Ignore
+ }
+
+ @Override
+ public void deactivated(ILaunchConfigurationWorkingCopy workingCopy)
+ {
+ // Ignore
+ }
+}
\ No newline at end of file
diff --git a/intrace.ecl.plugin/src/intrace/ecl/ui/launching/TabGroup.java b/intrace.ecl.plugin/src/intrace/ecl/ui/launching/TabGroup.java
index 96b043f..a272f5e 100644
--- a/intrace.ecl.plugin/src/intrace/ecl/ui/launching/TabGroup.java
+++ b/intrace.ecl.plugin/src/intrace/ecl/ui/launching/TabGroup.java
@@ -1,5 +1,7 @@
package intrace.ecl.ui.launching;
+import java.util.Arrays;
+
import intrace.ecl.Util;
import org.eclipse.core.runtime.CoreException;
@@ -20,6 +22,7 @@ public class TabGroup extends AbstractLaunchConfigurationTabGroup implements IEx
private static final String CONFIGATTR_TYPE = "type"; //$NON-NLS-1$
private ILaunchConfigurationTabGroup tabGroupDelegate;
+ private ILaunchConfigurationTab[] alltabs;
public void setInitializationData(IConfigurationElement config,
String propertyName, Object data) throws CoreException
@@ -67,11 +70,20 @@ public class TabGroup extends AbstractLaunchConfigurationTabGroup implements IEx
public void createTabs(ILaunchConfigurationDialog dialog, String mode)
{
tabGroupDelegate.createTabs(dialog, mode);
+ ILaunchConfigurationTab[] tabs = tabGroupDelegate.getTabs();
+ alltabs = new ILaunchConfigurationTab[tabs.length + 1];
+ alltabs[0] = tabs[0];
+ alltabs[1] = new InTraceLaunchConfigTab();
+ for (int ii = 2; ii < alltabs.length; ii++)
+ {
+ alltabs[ii] = tabs[ii - 1];
+ }
+ setTabs(alltabs);
}
@Override
public ILaunchConfigurationTab[] getTabs()
{
- return tabGroupDelegate.getTabs();
+ return alltabs;
}
}
diff --git a/intrace.ecl.plugin/src/intrace/ecl/ui/output/InTraceEditor.java b/intrace.ecl.plugin/src/intrace/ecl/ui/output/InTraceEditor.java
index abe8b2a..04dba1b 100644
--- a/intrace.ecl.plugin/src/intrace/ecl/ui/output/InTraceEditor.java
+++ b/intrace.ecl.plugin/src/intrace/ecl/ui/output/InTraceEditor.java
@@ -36,11 +36,8 @@ public class InTraceEditor extends EditorPart
// Do nothing
}
- @Override
- public void createPartControl(final Composite parent)
- {
- Composite ui = new Composite(parent, SWT.NONE);
-
+ public static UIModeData getUIModeData()
+ {
IWorkbench workBench = PlatformUI.getWorkbench();
ITheme theme = workBench.getThemeManager().getCurrentTheme();
ColorRegistry colreg = theme.getColorRegistry();
@@ -48,6 +45,15 @@ public class InTraceEditor extends EditorPart
Color c1 = colreg.get(IWorkbenchThemeConstants.ACTIVE_TAB_BG_START);
Color c2 = colreg.get(IWorkbenchThemeConstants.ACTIVE_TAB_BG_END);
UIModeData data = new UIModeData(c1, c2);
+ return data;
+ }
+
+ @Override
+ public void createPartControl(final Composite parent)
+ {
+ Composite ui = new Composite(parent, SWT.NONE);
+
+ UIModeData data = getUIModeData();
IWorkbench workbench = PlatformUI.getWorkbench();
final Display display = workbench.getDisplay();
diff --git a/org.intrace/lib/intrace-agent.jar b/org.intrace/lib/intrace-agent.jar
index 536b190..35f9dcf 100644
Binary files a/org.intrace/lib/intrace-agent.jar and b/org.intrace/lib/intrace-agent.jar differ
diff --git a/org.intrace/src/org/intrace/agent/AgentInit.java b/org.intrace/src/org/intrace/agent/AgentInit.java
index 7030666..3c792d1 100644
--- a/org.intrace/src/org/intrace/agent/AgentInit.java
+++ b/org.intrace/src/org/intrace/agent/AgentInit.java
@@ -70,6 +70,16 @@ public class AgentInit
e.printStackTrace();
}
}
+
+ // Setup shutdown hook
+ Runtime.getRuntime().addShutdownHook(new Thread()
+ {
+ @Override
+ public void run()
+ {
+ AgentHelper.gracefulShutdown();
+ }
+ });
}
public static synchronized void setServerPort(int xiServerPort)
diff --git a/org.intrace/src/org/intrace/client/gui/helper/ClientStrings.java b/org.intrace/src/org/intrace/client/gui/helper/ClientStrings.java
index 8fb6fde..fb1afcd 100644
--- a/org.intrace/src/org/intrace/client/gui/helper/ClientStrings.java
+++ b/org.intrace/src/org/intrace/client/gui/helper/ClientStrings.java
@@ -41,4 +41,15 @@ public class ClientStrings
public static final String FILTER_TEXT = "Filter...";
public static final String CANCEL_TEXT = "Cancel";
public static final String SAVE_TEXT = "Save...";
+
+ public static final String CLASS_TITLE = "Classes to Instrument";
+ public static final String CLASS_HELP_TEXT = "Enter complete or partial class names.\n\n "
+ + "e.g.\n"
+ + "\"mypack.mysubpack.MyClass\"\n"
+ + "\"MyClass\"";
+
+ public static final String FILTER_HELP_TEXT = "Enter text to match against trace lines. " +
+ "You can match any part of the line. " +
+ "\n\nYou can also select some text and right click the " +
+ "selection to quickly add an include or exclude filter.\n";
}
diff --git a/org.intrace/src/org/intrace/client/gui/helper/InTraceUI.java b/org.intrace/src/org/intrace/client/gui/helper/InTraceUI.java
index 2c1ec3a..27ca8b4 100644
--- a/org.intrace/src/org/intrace/client/gui/helper/InTraceUI.java
+++ b/org.intrace/src/org/intrace/client/gui/helper/InTraceUI.java
@@ -73,8 +73,8 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
private static final Pattern TRACE_LINE = Pattern.compile("^\\[[^\\]]+]:(\\[[^\\]]+\\]:([^:]+:[^:]+)):.*");
- private static final Pattern ALLOW_ALL = Pattern.compile(".*");
- private static final Pattern ALLOW_CLASSES = Pattern.compile("^[0-9a-zA-Z\\.\\$]*|\\*$");
+ public static final Pattern ALLOW_ALL = Pattern.compile(".*");
+ public static final Pattern ALLOW_CLASSES = Pattern.compile("^[0-9a-zA-Z\\.\\$]*|\\*$");
public void open()
{
@@ -297,7 +297,6 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
private final boolean tahomaUIFont;
private final Button connectButton;
private final Button settingsButton;
-
private MainBar(Composite parent)
{
composite = new Composite(parent, SWT.NONE);
@@ -407,10 +406,6 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
}
});
- final String helpText = "Enter complete or partial class names.\n\n "
- + "e.g.\n"
- + "\"mypack.mysubpack.MyClass\"\n"
- + "\"MyClass\"";
classesButton
.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter()
{
@@ -418,7 +413,7 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
public void widgetSelected(SelectionEvent arg0)
{
IncludeExcludeWindow regexInput = new IncludeExcludeWindow(
- "Classes to Instrument", helpText, mode,
+ ClientStrings.CLASS_TITLE, ClientStrings.CLASS_HELP_TEXT, mode,
modeData,
new PatternInputCallback()
{
@@ -456,34 +451,6 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
});
}
- private List getListFromString(String pattern)
- {
- List items = new ArrayList();
- String[] patternParts = pattern.split("\\|");
- for (String part : patternParts)
- {
- items.add(part);
- }
- return items;
- }
-
- private String getStringFromList(List list)
- {
- StringBuilder str = new StringBuilder();
-
- for (int ii = 0; ii < list.size(); ii++)
- {
- String item = list.get(ii);
- str.append(item);
- if (ii < (list.size() - 1))
- {
- str.append("|");
- }
- }
-
- return str.toString();
- }
-
private void setStatus(int instruClasses, int totalClasses)
{
if (!sRoot.isDisposed())
@@ -1419,12 +1386,7 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
}
}
}
- });
-
- final String helpText = "Enter text to match against trace lines. " +
- "You can match any part of the line. " +
- "\n\nYou can also select some text and right click the " +
- "selection to quickly add an include or exclude filter.\n";
+ });
final PatternInputCallback patternCallback = new PatternInputCallback()
{
@@ -1472,7 +1434,7 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
public void widgetSelected(SelectionEvent arg0)
{
IncludeExcludeWindow regexInput;
- regexInput = new IncludeExcludeWindow("Output Filter", helpText, mode,
+ regexInput = new IncludeExcludeWindow("Output Filter", ClientStrings.FILTER_HELP_TEXT, mode,
modeData,
patternCallback, lastEnteredIncludeFilterPattern,
lastEnteredExcludeFilterPattern, ALLOW_ALL);
@@ -2288,7 +2250,7 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
}
}
- private static void placeDialogInCenter(Rectangle parentSize, Shell shell)
+ public static void placeDialogInCenter(Rectangle parentSize, Shell shell)
{
Rectangle mySize = shell.getBounds();
@@ -2306,6 +2268,34 @@ public class InTraceUI implements ISocketCallback, IControlConnectionListener
outputTabs.textOutputTab.filterThread.interrupt();
}
+ public static List getListFromString(String pattern)
+ {
+ List items = new ArrayList();
+ String[] patternParts = pattern.split("\\|");
+ for (String part : patternParts)
+ {
+ items.add(part);
+ }
+ return items;
+ }
+
+ public static String getStringFromList(List list)
+ {
+ StringBuilder str = new StringBuilder();
+
+ for (int ii = 0; ii < list.size(); ii++)
+ {
+ String item = list.get(ii);
+ str.append(item);
+ if (ii < (list.size() - 1))
+ {
+ str.append("|");
+ }
+ }
+
+ return str.toString();
+ }
+
public static Image[] getIcons(Display display) throws IOException
{
// Load icons
diff --git a/org.intrace/src/org/intrace/output/AgentHelper.java b/org.intrace/src/org/intrace/output/AgentHelper.java
index 958ec9b..5ceddcd 100644
--- a/org.intrace/src/org/intrace/output/AgentHelper.java
+++ b/org.intrace/src/org/intrace/output/AgentHelper.java
@@ -150,6 +150,21 @@ public class AgentHelper
}
}
}
+
+ /**
+ * Allow any network output to gracefully shutdown
+ */
+ public static void gracefulShutdown()
+ {
+ Set networkThreads = networkOutputThreads.keySet();
+ if (networkThreads.size() > 0)
+ {
+ for (NetworkDataSenderThread thread : networkThreads)
+ {
+ thread.gracefulShutdown();
+ }
+ }
+ }
public static final CriticalBlock INSTRU_CRITICAL_BLOCK = new CriticalBlock();
private static class CriticalBlock implements Thread.UncaughtExceptionHandler
diff --git a/org.intrace/src/org/intrace/output/NetworkDataSenderThread.java b/org.intrace/src/org/intrace/output/NetworkDataSenderThread.java
index f890e65..5f211e2 100644
--- a/org.intrace/src/org/intrace/output/NetworkDataSenderThread.java
+++ b/org.intrace/src/org/intrace/output/NetworkDataSenderThread.java
@@ -119,4 +119,19 @@ public class NetworkDataSenderThread extends InstruRunnable
stop();
}
}
+
+ public void gracefulShutdown()
+ {
+ while(!outgoingData.isEmpty())
+ {
+ try
+ {
+ Thread.sleep(100);
+ }
+ catch (InterruptedException e)
+ {
+ // Ignore
+ }
+ }
+ }
}