Skip to content

Commit

Permalink
[GRASS] mutex function called by browser item (fixes crash in simulta…
Browse files Browse the repository at this point in the history
…neous loading, e.g. state restore)
  • Loading branch information
blazek committed Apr 1, 2015
1 parent d8bd20e commit da527e7
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/providers/grass/qgsgrass.cpp
Expand Up @@ -57,6 +57,9 @@ extern "C"
#define G__setenv(name,value) G__setenv( ( char * ) (name), (char *) (value) ) #define G__setenv(name,value) G__setenv( ( char * ) (name), (char *) (value) )
#endif #endif


#define GRASS_LOCK sMutex.lock();
#define GRASS_UNLOCK sMutex.unlock();

#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#include <windows.h> #include <windows.h>
QString GRASS_LIB_EXPORT QgsGrass::shortPath( const QString &path ) QString GRASS_LIB_EXPORT QgsGrass::shortPath( const QString &path )
Expand Down Expand Up @@ -411,13 +414,18 @@ QString QgsGrass::mMapsetLock;
QString QgsGrass::mGisrc; QString QgsGrass::mGisrc;
QString QgsGrass::mTmp; QString QgsGrass::mTmp;


QMutex QgsGrass::sMutex;

int QgsGrass::error_routine( char *msg, int fatal ) int QgsGrass::error_routine( char *msg, int fatal )
{ {
return error_routine(( const char* ) msg, fatal ); return error_routine(( const char* ) msg, fatal );
} }


int QgsGrass::error_routine( const char *msg, int fatal ) int QgsGrass::error_routine( const char *msg, int fatal )
{ {
// G_fatal_error obviously is not thread safe (everything static in GRASS, especially fatal_jmp_buf)
// it means that anything which may end up with G_fatal_error must use mutex

// Unfortunately the exceptions thrown here can only be caught if GRASS libraries are compiled // Unfortunately the exceptions thrown here can only be caught if GRASS libraries are compiled
// with -fexception option on Linux (works on Windows) // with -fexception option on Linux (works on Windows)
// GRASS developers are reluctant to add -fexception by default // GRASS developers are reluctant to add -fexception by default
Expand Down Expand Up @@ -802,6 +810,7 @@ QStringList GRASS_LIB_EXPORT QgsGrass::vectors( QString mapsetPath )
QStringList GRASS_LIB_EXPORT QgsGrass::vectorLayers( QString gisdbase, QStringList GRASS_LIB_EXPORT QgsGrass::vectorLayers( QString gisdbase,
QString location, QString mapset, QString mapName ) QString location, QString mapset, QString mapName )
{ {
GRASS_LOCK
QgsDebugMsg( QString( "gisdbase = %1 location = %2 mapset = %3 mapName = %4" ).arg( gisdbase ).arg( location ).arg( mapset ).arg( mapName ) ); QgsDebugMsg( QString( "gisdbase = %1 location = %2 mapset = %3 mapName = %4" ).arg( gisdbase ).arg( location ).arg( mapset ).arg( mapName ) );
QStringList list; QStringList list;


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


Expand All @@ -839,12 +849,14 @@ QStringList GRASS_LIB_EXPORT QgsGrass::vectorLayers( QString gisdbase,
#ifndef Q_OS_WIN #ifndef Q_OS_WIN
Vect_close( &map ); Vect_close( &map );
#endif #endif
GRASS_UNLOCK
return list; return list;
} }
else if ( level < 1 ) else if ( level < 1 )
{ {
QgsDebugMsg( "Cannot open vector" ); QgsDebugMsg( "Cannot open vector" );
QMessageBox::warning( 0, QObject::tr( "Warning" ), QObject::tr( "Cannot open vector %1 in mapset %2" ).arg( mapName ).arg( mapset ) ); QMessageBox::warning( 0, QObject::tr( "Warning" ), QObject::tr( "Cannot open vector %1 in mapset %2" ).arg( mapName ).arg( mapset ) );
GRASS_UNLOCK
return list; return list;
} }


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


Vect_close( &map ); Vect_close( &map );


GRASS_UNLOCK
return list; return list;
} }


Expand Down
4 changes: 4 additions & 0 deletions src/providers/grass/qgsgrass.h
Expand Up @@ -16,6 +16,8 @@
#ifndef QGSGRASS_H #ifndef QGSGRASS_H
#define QGSGRASS_H #define QGSGRASS_H


#include <QMutex>

#include <setjmp.h> #include <setjmp.h>


// GRASS header files // GRASS header files
Expand Down Expand Up @@ -308,6 +310,8 @@ class QgsGrass
static QString mGisrc; static QString mGisrc;
// Temporary directory where GISRC and sockets are stored // Temporary directory where GISRC and sockets are stored
static QString mTmp; static QString mTmp;
// Mutex for common locking when calling GRASS functions which are mostly non thread safe
static QMutex sMutex;
}; };


#endif // QGSGRASS_H #endif // QGSGRASS_H

0 comments on commit da527e7

Please sign in to comment.