Omaha #3810 Make D2D nsharp more thread safe.

Former-commit-id: 31901b563e4169cc44494134e3cac55a5542a79f
This commit is contained in:
Ben Steffensmeier 2014-11-12 14:47:39 -06:00
parent 334d738c79
commit 376f566451
3 changed files with 78 additions and 63 deletions

View file

@ -1,8 +0,0 @@
#Sat Apr 09 08:47:34 CDT 2011
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6

View file

@ -2,9 +2,9 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: D2D Nsharp
Bundle-SymbolicName: com.raytheon.uf.viz.d2d.nsharp;singleton:=true
Bundle-Version: 1.14.0.qualifier
Bundle-Version: 1.14.1.qualifier
Bundle-Vendor: RAYTHEON
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ActivationPolicy: lazy
Require-Bundle: com.raytheon.uf.viz.core;bundle-version="1.14.0",
com.raytheon.viz.ui;bundle-version="1.14.0",

View file

@ -45,7 +45,7 @@ import com.raytheon.uf.viz.core.drawables.IRenderableDisplay;
import com.raytheon.uf.viz.core.drawables.PaintProperties;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
import com.raytheon.uf.viz.core.rsc.IResourceDataChanged;
import com.raytheon.uf.viz.core.rsc.IResourceDataChanged.ChangeType;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
import com.raytheon.uf.viz.core.rsc.RenderingOrderFactory.ResourceOrder;
import com.raytheon.uf.viz.core.rsc.ResourceProperties;
@ -53,7 +53,7 @@ import com.raytheon.uf.viz.d2d.nsharp.display.D2DNSharpPartListener;
/**
*
* Minimal wrapper arounf ncep resource to handle updates and frame counts and
* Minimal wrapper around ncep resource to handle updates and frame counts and
* initializing data from a requestable resource data.
*
* <pre>
@ -61,8 +61,9 @@ import com.raytheon.uf.viz.d2d.nsharp.display.D2DNSharpPartListener;
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* ------------- -------- ----------- --------------------------
* Apr 14, 2011 bsteffen Initial creation
* Nov 12, 2014 3810 bsteffen Synchronize access to dataTimes and pdos.
*
* </pre>
*
@ -72,7 +73,10 @@ import com.raytheon.uf.viz.d2d.nsharp.display.D2DNSharpPartListener;
public class D2DNSharpResource extends
AbstractVizResource<D2DNSharpResourceData, AbstractDescriptor> {
// A map of all the plugin data objects for times we have data.
/* This object should be synchronized whenever accessing dataTimes or pdos. */
private final Object timeLock = new Object();
/* A map of all the plugin data objects for times we have data. */
private Map<DataTime, D2DNSharpDataObject> pdos = new HashMap<DataTime, D2DNSharpDataObject>();
private List<String> soundingsToRemove = new ArrayList<String>();
@ -87,13 +91,12 @@ public class D2DNSharpResource extends
protected IStatus run(IProgressMonitor monitor) {
D2DNSharpDataObject pdo = dataRequestQueue.poll();
while (pdo != null && !monitor.isCanceled()) {
if (pdos.get(pdo.getDataTime()) != pdo) {
pdo = dataRequestQueue.poll();
continue;
}
if (isDataObjectCurrent(pdo)) {
resourceData.populateDataObject(pdo);
dataResponseQueue.add(pdo);
issueRefresh();
}
pdo = dataRequestQueue.poll();
}
return Status.OK_STATUS;
@ -106,15 +109,19 @@ public class D2DNSharpResource extends
public D2DNSharpResource(D2DNSharpResourceData resourceData,
LoadProperties loadProperties) {
super(resourceData, loadProperties);
synchronized (timeLock) {
this.dataTimes = new ArrayList<DataTime>();
}
}
protected void addDataObject(D2DNSharpDataObject pdo) {
synchronized (timeLock) {
if (!this.dataTimes.contains(pdo.getDataTime())) {
this.dataTimes.add(pdo.getDataTime());
Collections.sort(this.dataTimes);
}
pdos.put(pdo.getDataTime(), pdo);
}
dataRequestQueue.offer(pdo);
dataRequestJob.schedule();
}
@ -123,9 +130,11 @@ public class D2DNSharpResource extends
protected void paintInternal(IGraphicsTarget target,
PaintProperties paintProps) throws VizException {
NsharpResourceHandler handler = getHandler();
// Last time I checked if you try to add or remove data from nsharp on
// non-UI threads it can cause major sync issues so all changes to
// nsharp are done in the paint loop.
/*
* Last time I checked if you try to add or remove data from nsharp on
* non-UI threads it can cause major sync issues so all changes to
* nsharp are done in the paint loop.
*/
if (!soundingsToRemove.isEmpty()) {
List<String> soundingsToRemove = this.soundingsToRemove;
this.soundingsToRemove = new ArrayList<String>();
@ -137,12 +146,9 @@ public class D2DNSharpResource extends
Map<String, List<NcSoundingLayer>> myDataMap = new HashMap<String, List<NcSoundingLayer>>();
D2DNSharpDataObject pdo = dataResponseQueue.poll();
while (pdo != null) {
if (pdos.get(pdo.getDataTime()) == pdo) {
if (pdo.getLayers() != null) {
if (isDataObjectCurrent(pdo) && pdo.getLayers() != null) {
stnInfo = pdo.getStationInfo();
myDataMap.put(stnInfo.getStnDisplayInfo(),
pdo.getLayers());
}
myDataMap.put(stnInfo.getStnDisplayInfo(), pdo.getLayers());
}
pdo = dataResponseQueue.poll();
}
@ -154,7 +160,7 @@ public class D2DNSharpResource extends
}
}
private NsharpResourceHandler getHandler() throws VizException {
private NsharpResourceHandler getHandler() {
List<NsharpAbstractPaneResource> paneRscs = descriptor
.getResourceList().getResourcesByTypeAsType(
NsharpAbstractPaneResource.class);
@ -176,13 +182,13 @@ public class D2DNSharpResource extends
@Override
protected void initInternal(IGraphicsTarget target) throws VizException {
getHandler().setSoundingType(resourceData.getSoundingType());
// listen for updates
resourceData.addChangeListener(new IResourceDataChanged() {
partListener = new D2DNSharpPartListener(this);
partListener.enable();
}
@Override
public void resourceChanged(ChangeType type, Object object) {
if (type == ChangeType.DATA_UPDATE
&& object instanceof Object[]) {
protected void resourceDataChanged(ChangeType type, Object object) {
if (type == ChangeType.DATA_UPDATE && object instanceof Object[]) {
for (Object obj : (Object[]) object) {
if (obj instanceof D2DNSharpDataObject) {
addDataObject((D2DNSharpDataObject) obj);
@ -191,22 +197,19 @@ public class D2DNSharpResource extends
}
}
});
partListener = new D2DNSharpPartListener(this);
partListener.enable();
}
@Override
public void remove(DataTime dataTime) {
D2DNSharpDataObject pdo = null;
synchronized (timeLock) {
pdo = pdos.remove(dataTime);
dataTimes.remove(dataTime);
}
if (pdo != null) {
NsharpStationInfo stnInfo = pdo.getStationInfo();
if (stnInfo != null) {
soundingsToRemove.add(stnInfo.getStnDisplayInfo());
}
}
dataTimes.remove(dataTime);
}
@Override
@ -223,8 +226,11 @@ public class D2DNSharpResource extends
public Collection<String> getTimeLineElements() {
List<String> elements = new ArrayList<String>();
synchronized (timeLock) {
for (DataTime time : dataTimes) {
elements.add(pdos.get(time).getStationInfo().getStnDisplayInfo());
elements.add(pdos.get(time).getStationInfo()
.getStnDisplayInfo());
}
}
return elements;
}
@ -237,18 +243,35 @@ public class D2DNSharpResource extends
@Override
public ResourceOrder getResourceOrder() {
// Have to be highest resource since the builtin nsharp resources are
// unknown and they have to be at index 0 on the list or nsharp code
// breaks.
/*
* Have to be highest resource since the builtin nsharp resources are
* unknown and they have to be at index 0 on the list or nsharp code
* breaks.
*/
return ResourceOrder.HIGHEST;
}
@Override
protected void setProperties(ResourceProperties properties) {
// Have to be highest resource since the builtin nsharp resources are
// unknown and they have to be at index 0 on the list or nsharp code
// breaks.
/*
* Have to be highest resource since the builtin nsharp resources are
* unknown and they have to be at index 0 on the list or nsharp code
* breaks.
*/
properties.setRenderingOrder(ResourceOrder.HIGHEST);
}
@Override
public DataTime[] getDataTimes() {
synchronized (timeLock) {
return super.getDataTimes();
}
}
private boolean isDataObjectCurrent(D2DNSharpDataObject pdo) {
synchronized (timeLock) {
return pdos.get(pdo.getDataTime()) == pdo;
}
}
}