DataLayer: thread-safety [message #1064734] |
Thu, 20 June 2013 13:33  |
Eclipse User |
|
|
|
Hi
What is the preferred way to asynchronously update the data-provider of a NatTable using glazed lists ? Do all the updates to the data-provider have to be performed by the UI thread or can it be updated asynchronously by a separate worker thread and leverage the glazed lists event mechanism to trigger a thread-safe repaint of the table?
I'm currently using a BasicEventList (wrapped using GlazedLists.threadSafeList) as data-provider of the NatTable. A worker thread updates the list which automatically triggers a repaint of the table by the UI thread. Things work fine if the worker thread updates (inserts/removes) elements at low frequency but as the worker thread increases the updates I'm starting to see IndexOutOfBoundsExceptions in the UI thread (see stack trace below).
A closer look at the DataLayer.getDataValueByPosition() method shows that the calculation of the index and the access to the element using that index is implemented with two separate calls to the data-provider. Even if the data-provider itself is thread-safe it looks like the calculated index may be invalid if the worker thread removes the appropriate element in between these two calls. Some additional locking of the data-provider seems to be required to avoid this inconsistency.
I'm using the NatTable 1.0.0 release with GlazedLists 1.9 from Orbit.
Thanks
Steve
java.lang.IndexOutOfBoundsException: Cannot get at 6 on list of size 0
at ca.odell.glazedlists.TransformedList.get(TransformedList.java:105)
at ca.odell.glazedlists.TransformedList.get(TransformedList.java:106)
at org.eclipse.nebula.widgets.nattable.data.ListDataProvider.getDataValue(ListDataProvider.java:45)
at org.eclipse.nebula.widgets.nattable.layer.DataLayer.getDataValueByPosition(DataLayer.java:311)
at org.eclipse.nebula.widgets.nattable.layer.AbstractLayerTransform.getDataValueByPosition(AbstractLayerTransform.java:331)
at org.eclipse.nebula.widgets.nattable.layer.AbstractLayerTransform.getDataValueByPosition(AbstractLayerTransform.java:331)
at org.eclipse.nebula.widgets.nattable.layer.AbstractLayerTransform.getDataValueByPosition(AbstractLayerTransform.java:331)
at org.eclipse.nebula.widgets.nattable.layer.AbstractLayerTransform.getDataValueByPosition(AbstractLayerTransform.java:331)
at org.eclipse.nebula.widgets.nattable.layer.AbstractIndexLayerTransform.getDataValueByPosition(AbstractIndexLayerTransform.java:333)
at org.eclipse.nebula.widgets.nattable.layer.AbstractLayerTransform.getDataValueByPosition(AbstractLayerTransform.java:331)
at org.eclipse.nebula.widgets.nattable.layer.CompositeLayer.getDataValueByPosition(CompositeLayer.java:548)
at org.eclipse.nebula.widgets.nattable.layer.AbstractLayerTransform.getDataValueByPosition(AbstractLayerTransform.java:331)
at org.eclipse.nebula.widgets.nattable.layer.CompositeLayer.getDataValueByPosition(CompositeLayer.java:548)
at org.eclipse.nebula.widgets.nattable.layer.cell.AbstractLayerCell.getDataValue(AbstractLayerCell.java:58)
at org.eclipse.nebula.widgets.nattable.layer.cell.CellDisplayConversionUtils.convertDataType(CellDisplayConversionUtils.java:20)
at org.eclipse.nebula.widgets.nattable.painter.cell.AbstractTextPainter.convertDataType(AbstractTextPainter.java:141)
at org.eclipse.nebula.widgets.nattable.painter.cell.TextPainter.paintCell(TextPainter.java:132)
at org.eclipse.nebula.widgets.nattable.painter.cell.CellPainterWrapper.paintCell(CellPainterWrapper.java:61)
at org.eclipse.nebula.widgets.nattable.painter.cell.decorator.PaddingDecorator.paintCell(PaddingDecorator.java:71)
at org.eclipse.nebula.widgets.nattable.painter.cell.CellPainterWrapper.paintCell(CellPainterWrapper.java:61)
at org.eclipse.nebula.widgets.nattable.painter.cell.decorator.LineBorderDecorator.paintCell(LineBorderDecorator.java:74)
at org.eclipse.nebula.widgets.nattable.painter.layer.CellLayerPainter.paintCell(CellLayerPainter.java:114)
at org.eclipse.nebula.widgets.nattable.selection.SelectionLayerPainter.paintCell(SelectionLayerPainter.java:152)
at org.eclipse.nebula.widgets.nattable.painter.layer.CellLayerPainter.paintLayer(CellLayerPainter.java:49)
at org.eclipse.nebula.widgets.nattable.painter.layer.GridLineCellLayerPainter.paintLayer(GridLineCellLayerPainter.java:42)
at org.eclipse.nebula.widgets.nattable.selection.SelectionLayerPainter.paintLayer(SelectionLayerPainter.java:43)
at org.eclipse.nebula.widgets.nattable.layer.CompositeLayer$CompositeLayerPainter.paintLayer(CompositeLayer.java:862)
at org.eclipse.nebula.widgets.nattable.freeze.CompositeFreezeLayer$FreezableLayerPainter.paintLayer(CompositeFreezeLayer.java:177)
at org.eclipse.nebula.widgets.nattable.layer.CompositeLayer$CompositeLayerPainter.paintLayer(CompositeLayer.java:862)
at org.eclipse.nebula.widgets.nattable.painter.layer.NatLayerPainter.paintLayer(NatLayerPainter.java:36)
at org.eclipse.nebula.widgets.nattable.NatTable.paintNatTable(NatTable.java:341)
at org.eclipse.nebula.widgets.nattable.NatTable.paintControl(NatTable.java:337)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:230)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4136)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1458)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1481)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1466)
at org.eclipse.swt.widgets.Control.drawWidget(Control.java:1244)
at org.eclipse.swt.widgets.Canvas.drawWidget(Canvas.java:167)
at org.eclipse.swt.widgets.Widget.drawRect(Widget.java:741)
at org.eclipse.swt.widgets.Canvas.drawRect(Canvas.java:162)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:5473)
at org.eclipse.swt.internal.cocoa.OS.objc_msgSendSuper(Native Method)
at org.eclipse.swt.widgets.Display.applicationNextEventMatchingMask(Display.java:4875)
at org.eclipse.swt.widgets.Display.applicationProc(Display.java:5241)
at org.eclipse.swt.internal.cocoa.OS.objc_msgSend(Native Method)
at org.eclipse.swt.internal.cocoa.NSApplication.nextEventMatchingMask(NSApplication.java:94)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3615)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1053)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:942)
at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:86)
at org.eclipse.e4.ui.internal.workbench.swt.E4Application.start(E4Application.java:150)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:353)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:180)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:629)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584)
at org.eclipse.equinox.launcher.Main.run(Main.java:1438)
at org.eclipse.equinox.launcher.Main.main(Main.java:1414)
Error while painting table: Cannot get at 6 on list of size 0
|
|
|
|
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.06342 seconds