Skip to content

Mouse Motion listener access the data using an iterator when it may modified by another thread #1

@simonduf

Description

@simonduf

Exception occurs in ATrace2D.getNearestPointEuclid(...) because the size of the trace is modified between it.hasNext() and it.next().

while (it.hasNext()) {
      point = it.next();               <-- here!!!
        ...
      }

This happens because we access in the Chart2D.PointHighlighter.mouseMoved(..) callback use getNearestPoint without synchronising on anything.

    @Override
    public void mouseMoved(MouseEvent e) {
      ITracePoint2D point = Chart2D.this.getPointFinder().getNearestPoint(e, Chart2D.this);
      // don't work on empty charts:
      if (point != null) {
        ITracePoint2D previousHighlightedPoint = this.m_previousHighlighted.get(point.getListener());
        if (!point.equals(previousHighlightedPoint)) {
          ITrace2D trace = point.getListener();
          // avoid duplicate or no highlighting in concurrent paint situation.
          synchronized (Chart2D.this) {
            synchronized (trace) {
              this.clearOutdatedHighlighters(trace);
              this.attachHighlighters(point);
              this.m_previousHighlighted.put(trace, point);
              Chart2D.this.setRequestedRepaint(true);
            }
          }
          Chart2D.this.notifyPointHighlightListeners(point);
        }
      }
    }

and no synchronisation is done deeper in the calls( getNearestPointManhattan and getNearestPointEuclid).

TODO: find where to lock the elements:
chart and trace should probably be lock as far down as possible, in getNearestPointEuclid.
The chart really need to be locked since the range of the chart could change...
and also to keep the synchronization order constant.

Full stack trace:

java.util.ConcurrentModificationException: null
	at java.util.TreeMap$PrivateEntryIterator.nextEntry(Unknown Source) ~[na:1.8.0_111]
	at java.util.TreeMap$KeyIterator.next(Unknown Source) ~[na:1.8.0_111]
	at info.monitorenter.gui.chart.traces.ATrace2D.getNearestPointEuclid(ATrace2D.java:1533) ~[jchart2d-code-0.0.1-rc.6.jar:na]
	at info.monitorenter.gui.chart.Chart2D.getNearestPointEuclid(Chart2D.java:2196) ~[jchart2d-code-0.0.1-rc.6.jar:na]
	at info.monitorenter.gui.chart.Chart2D$PointFinder$1.getNearestPoint(Chart2D.java:337) ~[jchart2d-code-0.0.1-rc.6.jar:na]
	at info.monitorenter.gui.chart.Chart2D$PointFinder.getNearestPoint(Chart2D.java:369) ~[jchart2d-code-0.0.1-rc.6.jar:na]
	at info.monitorenter.gui.chart.Chart2D$PointHighlighter.mouseMoved(Chart2D.java:468) ~[jchart2d-code-0.0.1-rc.6.jar:na]
	at java.awt.AWTEventMulticaster.mouseMoved(Unknown Source) ~[na:1.8.0_111]
	at java.awt.Component.processMouseMotionEvent(Unknown Source) ~[na:1.8.0_111]
	at javax.swing.JComponent.processMouseMotionEvent(Unknown Source) ~[na:1.8.0_111]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions