On 17 February 2012 15:15, <[email protected]> wrote:
> Author: pmouawad
> Date: Fri Feb 17 15:15:33 2012
> New Revision: 1245602
>
> URL: http://svn.apache.org/viewvc?rev=1245602&view=rev
> Log:
> Bug 52694 - Deadlock in GUI related to non AWT Threads updating GUI
>
> Modified:
>
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/AssertionVisualizer.java
>
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/ComparisonVisualizer.java
>
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/DistributionGraphVisualizer.java
>
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/GraphVisualizer.java
>
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/MailerVisualizer.java
>
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/SplineVisualizer.java
>
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatGraphVisualizer.java
>
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatVisualizer.java
>
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/SummaryReport.java
>
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/TableVisualizer.java
>
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/ViewResultsFullVisualizer.java
> jmeter/trunk/src/core/org/apache/jmeter/util/JMeterUtils.java
>
> jmeter/trunk/src/core/org/apache/jmeter/visualizers/SamplingStatCalculator.java
> jmeter/trunk/xdocs/changes.xml
>
> Modified:
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/AssertionVisualizer.java
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/AssertionVisualizer.java?rev=1245602&r1=1245601&r2=1245602&view=diff
> ==============================================================================
> ---
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/AssertionVisualizer.java
> (original)
> +++
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/AssertionVisualizer.java
> Fri Feb 17 15:15:33 2012
> @@ -50,14 +50,18 @@ public class AssertionVisualizer extends
> }
>
> public void add(SampleResult sample) {
> - StringBuilder sb = new StringBuilder(100);
> + final StringBuilder sb = new StringBuilder(100);
> sb.append(sample.getSampleLabel());
> sb.append(getAssertionResult(sample));
> sb.append("\n"); // $NON-NLS-1$
> - synchronized (textArea) {
> - textArea.append(sb.toString());
> - textArea.setCaretPosition(textArea.getText().length());
> - }
> + JMeterUtils.runSafe(new Runnable() {
> + public void run() {
> + synchronized (textArea) {
> + textArea.append(sb.toString());
StringBuilder is not thread-safe.
Probably won't cause an issue, but it would be safer to convert to
String which is passed to the runnable.
> + textArea.setCaretPosition(textArea.getText().length());
> + }
> + }
> + });
> }
>
> public void clearData() {
>
> Modified:
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/ComparisonVisualizer.java
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/ComparisonVisualizer.java?rev=1245602&r1=1245601&r2=1245602&view=diff
> ==============================================================================
> ---
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/ComparisonVisualizer.java
> (original)
> +++
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/ComparisonVisualizer.java
> Fri Feb 17 15:15:33 2012
> @@ -58,13 +58,16 @@ public class ComparisonVisualizer extend
> init();
> }
>
> - public void add(SampleResult sample) {
> -
> - DefaultMutableTreeNode currNode = new DefaultMutableTreeNode(sample);
> - treeModel.insertNodeInto(currNode, root, root.getChildCount());
> - if (root.getChildCount() == 1) {
> - resultsTree.expandPath(new TreePath(root));
> - }
> + public void add(final SampleResult sample) {
> + JMeterUtils.runSafe(new Runnable() {
> + public void run() {
> + DefaultMutableTreeNode currNode = new
> DefaultMutableTreeNode(sample);
> + treeModel.insertNodeInto(currNode, root,
> root.getChildCount());
> + if (root.getChildCount() == 1) {
> + resultsTree.expandPath(new TreePath(root));
> + }
> + }
> + });
> }
>
> public String getLabelResource() {
>
> Modified:
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/DistributionGraphVisualizer.java
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/DistributionGraphVisualizer.java?rev=1245602&r1=1245601&r2=1245602&view=diff
> ==============================================================================
> ---
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/DistributionGraphVisualizer.java
> (original)
> +++
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/DistributionGraphVisualizer.java
> Fri Feb 17 15:15:33 2012
> @@ -103,9 +103,14 @@ public class DistributionGraphVisualizer
> }
> }
>
> - public synchronized void add(SampleResult res) {
> - model.addSample(res);
> - updateGui(model.getCurrentSample());
> + public void add(final SampleResult res) {
> + JMeterUtils.runSafe(new Runnable() {
> + public void run() {
> + // made currentSample volatile
> + model.addSample(res);
> + updateGui(model.getCurrentSample());
> + }
> + });
> }
>
> public String getLabelResource() {
>
> Modified:
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/GraphVisualizer.java
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/GraphVisualizer.java?rev=1245602&r1=1245601&r2=1245602&view=diff
> ==============================================================================
> ---
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/GraphVisualizer.java
> (original)
> +++
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/GraphVisualizer.java
> Fri Feb 17 15:15:33 2012
> @@ -126,8 +126,12 @@ public class GraphVisualizer extends Abs
> updateYAxis();
> }
>
> - public void add(SampleResult res) {
> - updateGui(model.addSample(res));
> + public void add(final SampleResult res) {
> + JMeterUtils.runSafe(new Runnable() {
> + public void run() {
> + updateGui(model.addSample(res));
> + }
> + });
> }
>
> public String getLabelResource() {
>
> Modified:
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/MailerVisualizer.java
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/MailerVisualizer.java?rev=1245602&r1=1245601&r2=1245602&view=diff
> ==============================================================================
> ---
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/MailerVisualizer.java
> (original)
> +++
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/MailerVisualizer.java
> Fri Feb 17 15:15:33 2012
> @@ -122,11 +122,16 @@ public class MailerVisualizer extends Ab
> }
> }
>
> - public synchronized void add(SampleResult res) {
> + public void add(final SampleResult res) {
> if (getModel() != null) {
> - MailerModel model = ((MailerResultCollector)
> getModel()).getMailerModel();
> - model.add(res);//this is a different model from the one used by
> the result collector
> - updateVisualizer(model);
> + JMeterUtils.runSafe(new Runnable() {
> + public void run() {
> + MailerModel model = ((MailerResultCollector)
> getModel()).getMailerModel();
> + // method called by add is synchronized
> + model.add(res);//this is a different model from the one
> used by the result collector
> + updateVisualizer(model);
> + }
> + });
> }
> }
>
>
> Modified:
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/SplineVisualizer.java
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/SplineVisualizer.java?rev=1245602&r1=1245601&r2=1245602&view=diff
> ==============================================================================
> ---
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/SplineVisualizer.java
> (original)
> +++
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/SplineVisualizer.java
> Fri Feb 17 15:15:33 2012
> @@ -91,8 +91,12 @@ public class SplineVisualizer extends Ab
> setGUI();
> }
>
> - public void add(SampleResult res) {
> - model.add(res);
> + public void add(final SampleResult res) {
> + JMeterUtils.runSafe(new Runnable() {
> + public void run() {
> + model.add(res);
> + }
> + });
> }
>
> public String getLabelResource() {
>
> Modified:
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatGraphVisualizer.java
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatGraphVisualizer.java?rev=1245602&r1=1245601&r2=1245602&view=diff
> ==============================================================================
> ---
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatGraphVisualizer.java
> (original)
> +++
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatGraphVisualizer.java
> Fri Feb 17 15:15:33 2012
> @@ -268,8 +268,7 @@ public class StatGraphVisualizer extends
> return "aggregate_graph_title"; //$NON-NLS-1$
> }
>
> - public void add(SampleResult res) {
> - SamplingStatCalculator row = null;
> + public void add(final SampleResult res) {
> final String sampleLabel = res.getSampleLabel();
> Matcher matcher = null;
> if (columnSelection.isSelected() && columnMatchLabel.getText() !=
> null && columnMatchLabel.getText().length() > 0) {
> @@ -277,17 +276,22 @@ public class StatGraphVisualizer extends
> matcher = pattern.matcher(sampleLabel);
> }
> if ((matcher == null) || (matcher.find())) {
> - synchronized (lock) {
> - row = tableRows.get(sampleLabel);
> - if (row == null) {
> - row = new SamplingStatCalculator(sampleLabel);
> - tableRows.put(row.getLabel(), row);
> - model.insertRow(row, model.getRowCount() - 1);
> + JMeterUtils.runSafe(new Runnable() {
> + public void run() {
> + SamplingStatCalculator row = null;
> + synchronized (lock) {
> + row = tableRows.get(sampleLabel);
> + if (row == null) {
> + row = new SamplingStatCalculator(sampleLabel);
> + tableRows.put(row.getLabel(), row);
> + model.insertRow(row, model.getRowCount() - 1);
> + }
> + }
> + row.addSample(res);
> + tableRows.get(TOTAL_ROW_LABEL).addSample(res);
> + model.fireTableDataChanged();
> }
> - }
> - row.addSample(res);
> - tableRows.get(TOTAL_ROW_LABEL).addSample(res);
> - model.fireTableDataChanged();
> + });
> }
> }
>
>
> Modified:
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatVisualizer.java
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatVisualizer.java?rev=1245602&r1=1245601&r2=1245602&view=diff
> ==============================================================================
> ---
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatVisualizer.java
> (original)
> +++
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/StatVisualizer.java
> Fri Feb 17 15:15:33 2012
> @@ -163,28 +163,32 @@ public class StatVisualizer extends Abst
> return "aggregate_report"; //$NON-NLS-1$
> }
>
> - public void add(SampleResult res) {
> - SamplingStatCalculator row = null;
> - final String sampleLabel =
> res.getSampleLabel(useGroupName.isSelected());
> - synchronized (lock) {
> - row = tableRows.get(sampleLabel);
> - if (row == null) {
> - row = new SamplingStatCalculator(sampleLabel);
> - tableRows.put(row.getLabel(), row);
> - model.insertRow(row, model.getRowCount() - 1);
> + public void add(final SampleResult res) {
> + JMeterUtils.runSafe(new Runnable() {
> + public void run() {
> + SamplingStatCalculator row = null;
> + final String sampleLabel =
> res.getSampleLabel(useGroupName.isSelected());
> + synchronized (lock) {
> + row = tableRows.get(sampleLabel);
> + if (row == null) {
> + row = new SamplingStatCalculator(sampleLabel);
> + tableRows.put(row.getLabel(), row);
> + model.insertRow(row, model.getRowCount() - 1);
> + }
> + }
> + /*
> + * Synch is needed because multiple threads can update the
> counts.
> + */
> + synchronized(row) {
> + row.addSample(res);
> + }
> + SamplingStatCalculator tot = tableRows.get(TOTAL_ROW_LABEL);
> + synchronized(tot) {
> + tot.addSample(res);
> + }
> + model.fireTableDataChanged();
> }
> - }
> - /*
> - * Synch is needed because multiple threads can update the counts.
> - */
> - synchronized(row) {
> - row.addSample(res);
> - }
> - SamplingStatCalculator tot = tableRows.get(TOTAL_ROW_LABEL);
> - synchronized(tot) {
> - tot.addSample(res);
> - }
> - model.fireTableDataChanged();
> + });
> }
>
> /**
>
> Modified:
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/SummaryReport.java
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/SummaryReport.java?rev=1245602&r1=1245601&r2=1245602&view=diff
> ==============================================================================
> ---
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/SummaryReport.java
> (original)
> +++
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/SummaryReport.java
> Fri Feb 17 15:15:33 2012
> @@ -159,28 +159,32 @@ public class SummaryReport extends Abstr
> return "summary_report"; //$NON-NLS-1$
> }
>
> - public void add(SampleResult res) {
> - Calculator row = null;
> + public void add(final SampleResult res) {
> final String sampleLabel =
> res.getSampleLabel(useGroupName.isSelected());
> - synchronized (lock) {
> - row = tableRows.get(sampleLabel);
> - if (row == null) {
> - row = new Calculator(sampleLabel);
> - tableRows.put(row.getLabel(), row);
> - model.insertRow(row, model.getRowCount() - 1);
> + JMeterUtils.runSafe(new Runnable() {
> + public void run() {
> + Calculator row = null;
> + synchronized (lock) {
> + row = tableRows.get(sampleLabel);
> + if (row == null) {
> + row = new Calculator(sampleLabel);
> + tableRows.put(row.getLabel(), row);
> + model.insertRow(row, model.getRowCount() - 1);
> + }
> + }
> + /*
> + * Synch is needed because multiple threads can update the
> counts.
> + */
> + synchronized(row) {
> + row.addSample(res);
> + }
> + Calculator tot = tableRows.get(TOTAL_ROW_LABEL);
> + synchronized(tot) {
> + tot.addSample(res);
> + }
> + model.fireTableDataChanged();
> }
> - }
> - /*
> - * Synch is needed because multiple threads can update the counts.
> - */
> - synchronized(row) {
> - row.addSample(res);
> - }
> - Calculator tot = tableRows.get(TOTAL_ROW_LABEL);
> - synchronized(tot) {
> - tot.addSample(res);
> - }
> - model.fireTableDataChanged();
> + });
> }
>
> /**
>
> Modified:
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/TableVisualizer.java
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/TableVisualizer.java?rev=1245602&r1=1245601&r2=1245602&view=diff
> ==============================================================================
> ---
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/TableVisualizer.java
> (original)
> +++
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/TableVisualizer.java
> Fri Feb 17 15:15:33 2012
> @@ -155,34 +155,38 @@ public class TableVisualizer extends Abs
> deviationField.setText(Long.toString((long)
> calc.getStandardDeviation()));
> }
>
> - public void add(SampleResult res) {
> - if (childSamples.isSelected()) {
> - SampleResult[] subResults = res.getSubResults();
> - if (subResults.length > 0) {
> - for (SampleResult sr : subResults) {
> - add(sr);
> + public void add(final SampleResult res) {
> + JMeterUtils.runSafe(new Runnable() {
> + public void run() {
> + if (childSamples.isSelected()) {
> + SampleResult[] subResults = res.getSubResults();
> + if (subResults.length > 0) {
> + for (SampleResult sr : subResults) {
> + add(sr);
> + }
> + return;
> + }
> + }
> + synchronized (calc) {
> + calc.addSample(res);
> + int count = calc.getCount();
> + TableSample newS = new TableSample(
> + count,
> + res.getSampleCount(),
> + res.getStartTime(),
> + res.getThreadName(),
> + res.getSampleLabel(),
> + res.getTime(),
> + res.isSuccessful(),
> + res.getBytes());
> + model.addRow(newS);
> + }
> + updateTextFields(res);
> + if (autoscroll.isSelected()) {
> +
> table.scrollRectToVisible(table.getCellRect(table.getRowCount() - 1, 0,
> true));
> }
> - return;
> }
> - }
> - synchronized (calc) {
> - calc.addSample(res);
> - int count = calc.getCount();
> - TableSample newS = new TableSample(
> - count,
> - res.getSampleCount(),
> - res.getStartTime(),
> - res.getThreadName(),
> - res.getSampleLabel(),
> - res.getTime(),
> - res.isSuccessful(),
> - res.getBytes());
> - model.addRow(newS);
> - }
> - updateTextFields(res);
> - if (autoscroll.isSelected()) {
> - table.scrollRectToVisible(table.getCellRect(table.getRowCount()
> - 1, 0, true));
> - }
> + });
> }
>
> public synchronized void clearData() {
>
> Modified:
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/ViewResultsFullVisualizer.java
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/visualizers/ViewResultsFullVisualizer.java?rev=1245602&r1=1245601&r2=1245602&view=diff
> ==============================================================================
> ---
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/ViewResultsFullVisualizer.java
> (original)
> +++
> jmeter/trunk/src/components/org/apache/jmeter/visualizers/ViewResultsFullVisualizer.java
> Fri Feb 17 15:15:33 2012
> @@ -122,8 +122,12 @@ implements ActionListener, TreeSelection
> }
>
> /** {@inheritDoc} */
> - public void add(SampleResult sample) {
> - updateGui(sample);
> + public void add(final SampleResult sample) {
> + JMeterUtils.runSafe(new Runnable() {
> + public void run() {
> + updateGui(sample);
> + }
> + });
> }
>
> /**
>
> Modified: jmeter/trunk/src/core/org/apache/jmeter/util/JMeterUtils.java
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/util/JMeterUtils.java?rev=1245602&r1=1245601&r2=1245602&view=diff
> ==============================================================================
> --- jmeter/trunk/src/core/org/apache/jmeter/util/JMeterUtils.java (original)
> +++ jmeter/trunk/src/core/org/apache/jmeter/util/JMeterUtils.java Fri Feb 17
> 15:15:33 2012
> @@ -27,6 +27,7 @@ import java.io.FileInputStream;
> import java.io.IOException;
> import java.io.InputStream;
> import java.io.InputStreamReader;
> +import java.lang.reflect.InvocationTargetException;
> import java.net.InetAddress;
> import java.net.URL;
> import java.net.UnknownHostException;
> @@ -45,6 +46,7 @@ import javax.swing.ImageIcon;
> import javax.swing.JButton;
> import javax.swing.JComboBox;
> import javax.swing.JOptionPane;
> +import javax.swing.SwingUtilities;
>
> import org.apache.commons.io.IOUtils;
> import org.apache.jmeter.gui.GuiPackage;
> @@ -1264,5 +1266,23 @@ public class JMeterUtils implements Unit
> }
> return linkedHeaders;
> }
> -
> +
> + /**
> + * Run the runnable in AWT Thread if current thread is not AWT thread
> + * otherwise runs call {@link SwingUtilities#invokeAndWait(Runnable)}
> + * @param runnable {@link Runnable}
> + */
> + public static final void runSafe(Runnable runnable) {
> + if(SwingUtilities.isEventDispatchThread()) {
> + runnable.run();
> + } else {
> + try {
> + SwingUtilities.invokeAndWait(runnable);
> + } catch (InterruptedException e) {
> + throw new Error(e);
> + } catch (InvocationTargetException e) {
> + throw new Error(e);
> + }
> + }
> + }
> }
>
> Modified:
> jmeter/trunk/src/core/org/apache/jmeter/visualizers/SamplingStatCalculator.java
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/visualizers/SamplingStatCalculator.java?rev=1245602&r1=1245601&r2=1245602&view=diff
> ==============================================================================
> ---
> jmeter/trunk/src/core/org/apache/jmeter/visualizers/SamplingStatCalculator.java
> (original)
> +++
> jmeter/trunk/src/core/org/apache/jmeter/visualizers/SamplingStatCalculator.java
> Fri Feb 17 15:15:33 2012
> @@ -38,7 +38,7 @@ public class SamplingStatCalculator {
>
> private String label;
>
> - private Sample currentSample;
> + private volatile Sample currentSample;
>
> public SamplingStatCalculator(){ // Only for use by test code
> this("");
>
> Modified: jmeter/trunk/xdocs/changes.xml
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1245602&r1=1245601&r2=1245602&view=diff
> ==============================================================================
> --- jmeter/trunk/xdocs/changes.xml (original)
> +++ jmeter/trunk/xdocs/changes.xml Fri Feb 17 15:15:33 2012
> @@ -101,6 +101,7 @@ or a Debug Sampler with all fields set t
> <ul>
> <li>Bug 52639 - JSplitPane divider for log panel should be hidden if log is
> not activated</li>
> <li>Bug 52672 - Change Controller action deletes all but one child
> samplers</li>
> +<li>Bug 52694 - Deadlock in GUI related to non AWT Threads updating GUI</li>
> </ul>
>
> <!-- =================== Improvements =================== -->
>
>