|Version 5 (modified by warmerdam, 6 years ago)|
RFC 16: OGR Thread Safety
Author: Frank Warmerdam
In an effort to better support thread safety in OGR some methods are added as internal infrastructure is updated.
Reentrant: A reentrant function can be called simultaneously by multiple threads provided that each invocation of the function references unique data.
Thread-safe: A thread-safe function can be called simultaneously by multiple threads when each invocation references shared data. All access to the shared data is serialized.
To make all of the OGR core and selected drivers reentrant, and to make the driver registrar, drivers and datasources at least potentially thread-safe.
The TestCapability() method on the driver, and datasource will be extended to include ways of testing for reentrancy and thread safety on particular instances. The following macros will be added:
#define OLCReentrant "Reentrant" #define ODsReentrant "Reentrant" #define ODsThreadSafe "Threadsafe"
Note that layers cannot be threadsafe as long as layer feature reading status is implicit in the layer object. The default return value for all test values is FALSE, as is normal for the TestCapability() method, but specific drivers can return TRUE after determining that the driver datasources or layers are in fact reentrant and/or threadsafe.
Various changes have already been made to make the driver registrar thread safe, primarily by protecting operations on it with a mutex.
No changes are required to the OGRSFDriver base class for thread safety, primarily because it does almost nothing.
This class has been modified to include an m_hMutex class data member which is a mutex used to ensure thread safe access to internal datastructures such as the layer list. Classes derived from OGRDataSource that wish to implement threadsafe operation should use this mutex when exclusivity is required.
The default OGR implementation of OGRDataSource::ExecuteSQL() internally uses and modifies the layer state (feature iterators and filters) and as such is not appropriate to use on a datasource that is attempting to be threadsafe even though it is understood that individual layers are not threadsafe. The proposed solution is to offer an OGRTS "dialect" (OGR Thread Safe) which actually opens a duplicate (readonly) datasource so that there will be distinct instances of the layers for the use of the resulset from ExecuteSQL(). This is very expensive in terms of file access and file handles consumed so it is not the default. The default dialect (NULL, "" or "OGR") will continue to use the layers from the current datasource despite the various side effects implied.