Skip to content

Commit da527e7

Browse files
committed
[GRASS] mutex function called by browser item (fixes crash in simultaneous loading, e.g. state restore)
1 parent d8bd20e commit da527e7

File tree

2 files changed

+17
-0
lines changed

2 files changed

+17
-0
lines changed

src/providers/grass/qgsgrass.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ extern "C"
5757
#define G__setenv(name,value) G__setenv( ( char * ) (name), (char *) (value) )
5858
#endif
5959

60+
#define GRASS_LOCK sMutex.lock();
61+
#define GRASS_UNLOCK sMutex.unlock();
62+
6063
#ifdef Q_OS_WIN
6164
#include <windows.h>
6265
QString GRASS_LIB_EXPORT QgsGrass::shortPath( const QString &path )
@@ -411,13 +414,18 @@ QString QgsGrass::mMapsetLock;
411414
QString QgsGrass::mGisrc;
412415
QString QgsGrass::mTmp;
413416

417+
QMutex QgsGrass::sMutex;
418+
414419
int QgsGrass::error_routine( char *msg, int fatal )
415420
{
416421
return error_routine(( const char* ) msg, fatal );
417422
}
418423

419424
int QgsGrass::error_routine( const char *msg, int fatal )
420425
{
426+
// G_fatal_error obviously is not thread safe (everything static in GRASS, especially fatal_jmp_buf)
427+
// it means that anything which may end up with G_fatal_error must use mutex
428+
421429
// Unfortunately the exceptions thrown here can only be caught if GRASS libraries are compiled
422430
// with -fexception option on Linux (works on Windows)
423431
// GRASS developers are reluctant to add -fexception by default
@@ -802,6 +810,7 @@ QStringList GRASS_LIB_EXPORT QgsGrass::vectors( QString mapsetPath )
802810
QStringList GRASS_LIB_EXPORT QgsGrass::vectorLayers( QString gisdbase,
803811
QString location, QString mapset, QString mapName )
804812
{
813+
GRASS_LOCK
805814
QgsDebugMsg( QString( "gisdbase = %1 location = %2 mapset = %3 mapName = %4" ).arg( gisdbase ).arg( location ).arg( mapset ).arg( mapName ) );
806815
QStringList list;
807816

@@ -826,6 +835,7 @@ QStringList GRASS_LIB_EXPORT QgsGrass::vectorLayers( QString gisdbase,
826835
{
827836
Q_UNUSED( e );
828837
QgsDebugMsg( QString( "Cannot open GRASS vector: %1" ).arg( e.what() ) );
838+
GRASS_UNLOCK
829839
return list;
830840
}
831841

@@ -839,12 +849,14 @@ QStringList GRASS_LIB_EXPORT QgsGrass::vectorLayers( QString gisdbase,
839849
#ifndef Q_OS_WIN
840850
Vect_close( &map );
841851
#endif
852+
GRASS_UNLOCK
842853
return list;
843854
}
844855
else if ( level < 1 )
845856
{
846857
QgsDebugMsg( "Cannot open vector" );
847858
QMessageBox::warning( 0, QObject::tr( "Warning" ), QObject::tr( "Cannot open vector %1 in mapset %2" ).arg( mapName ).arg( mapset ) );
859+
GRASS_UNLOCK
848860
return list;
849861
}
850862

@@ -926,6 +938,7 @@ QStringList GRASS_LIB_EXPORT QgsGrass::vectorLayers( QString gisdbase,
926938

927939
Vect_close( &map );
928940

941+
GRASS_UNLOCK
929942
return list;
930943
}
931944

src/providers/grass/qgsgrass.h

+4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#ifndef QGSGRASS_H
1717
#define QGSGRASS_H
1818

19+
#include <QMutex>
20+
1921
#include <setjmp.h>
2022

2123
// GRASS header files
@@ -308,6 +310,8 @@ class QgsGrass
308310
static QString mGisrc;
309311
// Temporary directory where GISRC and sockets are stored
310312
static QString mTmp;
313+
// Mutex for common locking when calling GRASS functions which are mostly non thread safe
314+
static QMutex sMutex;
311315
};
312316

313317
#endif // QGSGRASS_H

0 commit comments

Comments
 (0)