mirror of
				https://github.com/subsurface/subsurface.git
				synced 2025-02-19 22:16:15 +00:00 
			
		
		
		
	TankBar: don't risk dereferencing stale pointers
Basically we could end up in a situation where the plotInfo is no longer valid, yet the model changes and triggers a redraw before the new data is passed into the TankBar. Instead of chasing that race condition it seemed much easier to just copy the plot_data entries and the gas information in the dive. Fixes #716 Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
		
							parent
							
								
									3e4c30735c
								
							
						
					
					
						commit
						fb371c0633
					
				
					 2 changed files with 20 additions and 12 deletions
				
			
		|  | @ -9,8 +9,8 @@ | ||||||
| TankItem::TankItem(QObject *parent) : | TankItem::TankItem(QObject *parent) : | ||||||
| 	QGraphicsRectItem(), | 	QGraphicsRectItem(), | ||||||
| 	dataModel(0), | 	dataModel(0), | ||||||
| 	dive(0), | 	pInfoEntry(0), | ||||||
| 	pInfo(0) | 	pInfoNr(0) | ||||||
| { | { | ||||||
| 	height = 3; | 	height = 3; | ||||||
| 	QColor red(PERSIANRED1); | 	QColor red(PERSIANRED1); | ||||||
|  | @ -30,12 +30,19 @@ TankItem::TankItem(QObject *parent) : | ||||||
| 	trimixGradient.setColorAt(1.0, red); | 	trimixGradient.setColorAt(1.0, red); | ||||||
| 	trimix = trimixGradient; | 	trimix = trimixGradient; | ||||||
| 	air = blue; | 	air = blue; | ||||||
|  | 	memset(&diveCylinderStore, 0, sizeof(diveCylinderStore)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void TankItem::setData(DivePlotDataModel *model, struct plot_info *plotInfo, struct dive *d) | void TankItem::setData(DivePlotDataModel *model, struct plot_info *plotInfo, struct dive *d) | ||||||
| { | { | ||||||
| 	pInfo = plotInfo; | 	free(pInfoEntry); | ||||||
| 	dive = d; | 	// the plotInfo and dive structures passed in could become invalid before we stop using them,
 | ||||||
|  | 	// so copy the data that we need
 | ||||||
|  | 	int size = plotInfo->nr * sizeof(plotInfo->entry[0]); | ||||||
|  | 	pInfoEntry = (struct plot_data *)malloc(size); | ||||||
|  | 	pInfoNr = plotInfo->nr; | ||||||
|  | 	memcpy(pInfoEntry, plotInfo->entry, size); | ||||||
|  | 	copy_cylinders(d, &diveCylinderStore, false); | ||||||
| 	dataModel = model; | 	dataModel = model; | ||||||
| 	connect(dataModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(modelDataChanged(QModelIndex, QModelIndex))); | 	connect(dataModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(modelDataChanged(QModelIndex, QModelIndex))); | ||||||
| 	modelDataChanged(); | 	modelDataChanged(); | ||||||
|  | @ -65,7 +72,7 @@ void TankItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &b | ||||||
| { | { | ||||||
| 	// We don't have enougth data to calculate things, quit.
 | 	// We don't have enougth data to calculate things, quit.
 | ||||||
| 
 | 
 | ||||||
| 	if (!dive || !dataModel || !pInfo || !pInfo->nr) | 	if (!dataModel || !pInfoEntry || !pInfoNr) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
| 	// remove the old rectangles
 | 	// remove the old rectangles
 | ||||||
|  | @ -75,21 +82,21 @@ void TankItem::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &b | ||||||
| 	rects.clear(); | 	rects.clear(); | ||||||
| 
 | 
 | ||||||
| 	// walk the list and figure out which tanks go where
 | 	// walk the list and figure out which tanks go where
 | ||||||
| 	struct plot_data *entry = pInfo->entry; | 	struct plot_data *entry = pInfoEntry; | ||||||
| 	int cylIdx = entry->cylinderindex; | 	int cylIdx = entry->cylinderindex; | ||||||
| 	int i = -1; | 	int i = -1; | ||||||
| 	int startTime = 0; | 	int startTime = 0; | ||||||
| 	struct gasmix *gas = &dive->cylinder[cylIdx].gasmix; | 	struct gasmix *gas = &diveCylinderStore.cylinder[cylIdx].gasmix; | ||||||
| 	qreal width, left; | 	qreal width, left; | ||||||
| 	while (++i < pInfo->nr) { | 	while (++i < pInfoNr) { | ||||||
| 		entry = &pInfo->entry[i]; | 		entry = &pInfoEntry[i]; | ||||||
| 		if (entry->cylinderindex == cylIdx) | 		if (entry->cylinderindex == cylIdx) | ||||||
| 			continue; | 			continue; | ||||||
| 		width = hAxis->posAtValue(entry->sec) - hAxis->posAtValue(startTime); | 		width = hAxis->posAtValue(entry->sec) - hAxis->posAtValue(startTime); | ||||||
| 		left = hAxis->posAtValue(startTime); | 		left = hAxis->posAtValue(startTime); | ||||||
| 		createBar(left, width, gas); | 		createBar(left, width, gas); | ||||||
| 		cylIdx = entry->cylinderindex; | 		cylIdx = entry->cylinderindex; | ||||||
| 		gas = &dive->cylinder[cylIdx].gasmix; | 		gas = &diveCylinderStore.cylinder[cylIdx].gasmix; | ||||||
| 		startTime = entry->sec; | 		startTime = entry->sec; | ||||||
| 	} | 	} | ||||||
| 	width = hAxis->posAtValue(entry->sec) - hAxis->posAtValue(startTime); | 	width = hAxis->posAtValue(entry->sec) - hAxis->posAtValue(startTime); | ||||||
|  |  | ||||||
|  | @ -28,8 +28,9 @@ private: | ||||||
| 	DivePlotDataModel *dataModel; | 	DivePlotDataModel *dataModel; | ||||||
| 	DiveCartesianAxis *hAxis; | 	DiveCartesianAxis *hAxis; | ||||||
| 	int hDataColumn; | 	int hDataColumn; | ||||||
| 	struct dive *dive; | 	struct dive diveCylinderStore; | ||||||
| 	struct plot_info *pInfo; | 	struct plot_data *pInfoEntry; | ||||||
|  | 	int pInfoNr; | ||||||
| 	qreal yPos, height; | 	qreal yPos, height; | ||||||
| 	QBrush air, nitrox, trimix; | 	QBrush air, nitrox, trimix; | ||||||
| 	QList<QGraphicsRectItem *> rects; | 	QList<QGraphicsRectItem *> rects; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue