mod_spatialite thread-safety

314 views
Skip to first unread message

Jorge Rocha Gualtieri

unread,
May 9, 2016, 2:53:24 PM5/9/16
to SpatiaLite Users
Hi,

I've been working on a C#/SQLite/SpatiaLite application. It's a multi-thread Windows service. 
I'm running SQLite with THREADSAFE=1.

I got a failed assert when running with multiple threads. If I place a mutex before issuing the statement everything runs ok.
Is SpatiaLite thread-safe? Are there compile directives to enable it?
If SpatiaLite isn't thread-safe, is it ok to just place a mutex before running statements or is there something that may get corrupted?


Assert:

File: geos_ts_c.cpp, Line 3657
Expression: 0 != cs

SQLite compile options: 

compile option: ENABLE_API_ARMOR
compile option: ENABLE_COLUMN_METADATA
compile option: ENABLE_DBSTAT_VTAB
compile option: ENABLE_FTS3
compile option: ENABLE_LOAD_EXTENSION
compile option: ENABLE_MEMORY_MANAGEMENT
compile option: ENABLE_RTREE
compile option: ENABLE_STAT4
compile option: HAS_CODEC
compile option: SOUNDEX
compile option: THREADSAFE=1
compile option: WIN32_MALLOC


Fault call stack:

ntdll!NtTerminateProcess+0x14
ntdll!RtlExitUserProcess+0xe5
KERNEL32!ExitProcessImplementation+0xa
mscoreei!RuntimeDesc::ShutdownAllActiveRuntimes+0x27b
MSCOREE!ShellShim_CorExitProcess+0xdd
msvcrt!_crtCorExitProcess+0x59
msvcrt!unlockexit+0xbe
msvcrt!abort+0xa0
libgeos_c_1!GEOSGeomToHEX_buf_r+0x2492
libgeos_c_1!GEOSGeomToHEX_buf_r+0x2548
libgeos_c_1!GEOSCoordSeq_setOrdinate_r+0xce
libgeos_c_1!GEOSCoordSeq_setX+0x2b
mod_spatialite!gaiaMakePolygon+0xec6
mod_spatialite!gaiaToGeos+0x25
mod_spatialite!gaiaGeomCollBuffer+0x4b
mod_spatialite!gaiaSpatialite2GPKG+0x353a2
SQLite_Interop!sqlite3_blob_open+0x1a7b
SQLite_Interop!sqlite3_step+0x300
SQLite_Interop!sqlite3_step+0x9c
0x00007ffe`5d4b4dbe
0x00007ffe`5d4b4d08
0x00007ffe`5d4b4a83
0x00007ffe`5d4b2f7f
0x00007ffe`5d4b2b84
0x00007ffe`5d4b248c
0x00007ffe`5d4b23a3
0x00007ffe`5d4b940e
mscorlib_ni+0x52a77e
mscorlib_ni+0x52a617
mscorlib_ni+0x52a5d2
mscorlib_ni+0x47bef2
clr!CallDescrWorkerInternal+0x83
clr!CallDescrWorkerWithHandler+0x4e
clr!MethodDescCallSite::CallTargetWorker+0xf8
clr! ?? ::FNODOBFM::`string'+0xc522f
clr!Frame::Push+0x1e1
clr!Frame::Push+0x16c
clr!Frame::Push+0x95
clr!ManagedPerAppDomainTPCount::DispatchWorkItem+0x1b7
clr!ThreadNative::KickOffThread+0xd6
clr!Thread::intermediateThreadProc+0x7d
KERNEL32!BaseThreadInitThunk+0x22
ntdll!RtlUserThreadStart+0x34

Query:

SELECT ROWID, Data
    FROM Cache
    WHERE ST_Contains(Geometry, MakePoint(@longitude, @latitude, 4326)) = 1
    AND ROWID IN (
        SELECT ROWID
        FROM SpatialIndex
        WHERE f_table_name = 'Cache'
        and f_geometry_column = 'Geometry'
        AND search_frame = MakePoint(@longitude, @latitude, 4326)
    )
    LIMIT 1


Tkz,
JRG

a.fu...@lqt.it

unread,
May 9, 2016, 4:05:29 PM5/9/16
to spatiali...@googlegroups.com
On Mon, 9 May 2016 11:53:24 -0700 (PDT), Jorge Rocha Gualtieri wrote:
> Is SpatiaLite thread-safe? Are there compile directives to enable it?
>

Hi Jorge,

SpatiaLite itself is expected to be thread-safe, but some
depending library isn't.
GEOS, PROJ.4 and LIBLWGEOM were not thread-safe in past
years, and only their most recent versions are expected
to be finally thread-safe.
please notice: your issue is actually caused by GEOS.

asking "is spatialite thread-safe ?" makes very little
technical sense if you omit to clearly specify:
- which version of libspatialite are you using
- and which version of GEOS, PROJ.4 (and may be of LWGEOM)

as a rule of the thumb, earlier versions (4.2 and 4.3)
are expected to be possibly affected by some residual
multi-threading issue (in decreasing severity).
the most recent 4.4 (when built on the top of the
latest GEOS 3.4.5 and RTTOPO) will be finally completely
thread-safe.


> If SpatiaLite isn't thread-safe, is it ok to just place a mutex
> before running statements or is there something that may get
> corrupted?
>

no, it will be completely harmless, but this way you will
obviously negate any possible speed benefit coming from
adopting a sophisticated multi-thread approach.
under such impaired conditions writing a conventional
single-thread application could probably run in a more
efficient way.

bye Sandro


Jorge Rocha Gualtieri

unread,
May 9, 2016, 5:55:12 PM5/9/16
to SpatiaLite Users
Hi Sandro,

Thanks for your prompt reply. I should've noticed by the call stack that the issue was related to GEOS lib, sorry about that.
I was using spatialite  4.3.0a (RTW binaries) when I got this issue. I've just swapped to 4.4.0-RC0 (RTW binaries) and it solved the problem. I guess it's built on the top of the latest GEOS 3.4.5 and RTTOPO, but I don't know for sure.

I don't know much about all those libs that are used into spatialite and their past or current thread support, but I think it's a very useful information.
Do you think it's worth to put this information at the wiki ( https://www.gaia-gis.it/fossil/libspatialite/wiki?name=thread-safe )? Do you know how can I do that or anything else I can do to help?

Thanks,
JRG

mj10777

unread,
May 10, 2016, 12:19:38 AM5/10/16
to SpatiaLite Users


On Monday, 9 May 2016 22:05:29 UTC+2, sandro furieri wrote:
On Mon, 9 May 2016 11:53:24 -0700 (PDT), Jorge Rocha Gualtieri wrote:
> Is SpatiaLite thread-safe? Are there compile directives to enable it?
>

Hi Jorge,

SpatiaLite itself is expected to be thread-safe, but some
depending library isn't.
GEOS, PROJ.4 and LIBLWGEOM were not thread-safe in past
years, and only their most recent versions are expected
to be finally thread-safe.
please notice: your issue is actually caused by GEOS.

asking "is spatialite thread-safe ?" makes very little
technical sense if you omit to clearly specify:
- which version of libspatialite are you using
- and which version of GEOS, PROJ.4 (and may be of LWGEOM)

as a rule of the thumb, earlier versions (4.2 and 4.3)
are expected to be possibly affected by some residual
multi-threading issue (in decreasing severity).
the most recent 4.4 (when built on the top of the
latest GEOS 3.4.5 and RTTOPO) will be finally completely
thread-safe.
This I assume should be GEOS 3.5.0 (released 16.08.2015), which was the last release.

a.fu...@lqt.it

unread,
May 10, 2016, 2:07:47 AM5/10/16
to spatiali...@googlegroups.com
On Mon, 9 May 2016 21:19:38 -0700 (PDT), 'mj10777' via SpatiaLite Users
wrote:
> On Monday, 9 May 2016 22:05:29 UTC+2, sandro furieri wrote:
>> as a rule of the thumb, earlier versions (4.2 and 4.3)
>> are expected to be possibly affected by some residual
>> multi-threading issue (in decreasing severity).
>> the most recent 4.4 (when built on the top of the
>> latest GEOS 3.4.5 and RTTOPO) will be finally completely
>> thread-safe.
>
> This I assume should be GEOS 3.5.0 (released 16.08.2015), which was
> the last release.
>

Hi Mark,

you are absolutely right, sorry for my previous typo.
GEOS 3.4.5 never existed; the next release immediately
following 3.4.2 (2013/08/25) is 3.5.0

bye Sandro

a.fu...@lqt.it

unread,
May 10, 2016, 3:18:00 AM5/10/16
to spatiali...@googlegroups.com
On Mon, 9 May 2016 14:55:12 -0700 (PDT), Jorge Rocha Gualtieri wrote:
> I don't know much about all those libs that are used into spatialite
> and their past or current thread support, but I think it's a very
> useful information.
>

Hi Jorge,

here is a very quick summary.

a. GEOS (https://trac.osgeo.org/geos/) is a C++ library implementing
a sophisticated Geometry Engine. SpatiaLite depends on GEOS when
complex operations involving geometries have to be computed.
Examples: ST_Length(), ST_Area(), ST_IsValid(), ST_Overlaps(),
ST_Crosses(), ST_Intersects(), ST_Union(), ST_Difference(),
ST_Intersection() ST_Buffer() and many others.
b. PROJ.4 (https://trac.osgeo.org/proj/) is a C library supporting
Cartographic Projections. SpatiaLite depends on PROJ.4 when
transforming coordinates between different Spatial Reference
Systems is required. Example: ST_Transform()
c. LWGEOM is another C library supporting advanced Geometry
and ISO-Topology operations; you can think of LWGEOM as
a more powerful GEOS further extending its basic
capabilities.
LWGEOM is integral part of PostGIS (http://postgis.net/).
in the past SpatiaLite depended on LWGEOM in order to
support e.g. ST_MakeValid(), ST_Split(), ST_Node() and
the whole ISO-Topology module.
d. RTTOPO (https://git.osgeo.org/gogs/rttopo/librttopo) is
a very recent C library (the first stable release is
expected in the next days) intended to be a full
LWGEOM replacement.
All future versions of SpatiaLite will definitely
dismiss LWGEOM and will support RTTOPO.


thread-safety evolution:
========================
- both PROJ.4 and GEOS were initially non-thread-safe;
in recent times practically all CPUs adopted a multi-core
architecture, so implementing a thread-safe design become
a strict requirement for many libraries.

- PROJ.4 transition toward thread-safety started since
version 4.7.0 and was basically simple.
Just a single initialization API changed, so correctly
supporting the new thread-safe mode of PROJ.4 was a
painless effort.
You can read further details from here:
https://trac.osgeo.org/proj/wiki/ThreadSafety

- GEOS adopted a more disruptive approach; all APIs were
doubled, so for the same function we usually have two
different flavors, the traditional non-thread-safe and
the new thread-safe sharing the same name but assuming
the "_r" suffix ("_r" stands for "reentrant")
Example: GEOSGeom_createPoint() vs GEOSGeom_createPoint_r()
Such an approach had a very heavy impact on SpatiaLite,
and practically required a radical rewrite of many
portions of the code. It's rather obvious that a
radical rewrite of many thousands lines of C code
opened the doors to many possible glitches and bugs,
thus requiring a further time to be carefully
debugged and fixed.
Anyway even the "new thread-safe APIs" of GEOS were
not completely thread-safe as they were intended to
be, and only the latest 3.5.0 definitely fixed the
problem in a fully consistent way.

- LWGEOM simply wasn't (and still isn't) thread-safe;
full stop.
(a short rationale: LWGEOM is integral part of
PostGIS, and the PortgreSQL own architecture never
depends on parallel thread; it depends on parallel
processes, that is a completely different story).
This forced SpatiaLite to carefully depend on
mutexes before and after each single call to LWGEOM.

- the brand new RTTOPO is instead thread-safe "by design",
and this is one of the strongest arguments explaining
why all future versions of SpatiaLite will adopt RTTOPO
as a full replacement to LWGEOM

bye Sandro

Jorge Rocha Gualtieri

unread,
May 10, 2016, 3:45:54 PM5/10/16
to SpatiaLite Users
Hi Sandro,

Thanks a lot for all information you provided me :) Now I understand a little bit how modules interact with each other. 
I've tried to publish this at wiki but it requires you to have user/pass. 

Congratulations to all you guys behind this amazing lib!

JRG

邹鲁

unread,
Oct 5, 2016, 1:56:26 PM10/5/16
to SpatiaLite Users
Hi,
I've encountered the same error while running demo2 from the official code base. 
lt-demo2: geos_ts_c.cpp:3657: int GEOSCoordSeq_setOrdinate_r(GEOSContextHandle_t, geos::geom::CoordinateSequence*, unsigned int, unsigned int, double): Assertion `0 != cs' failed.
[1]    15401 abort (core dumped)  ./demo2


And I've tried to convince myself that I might have done something wrong. So I've tested the code under the following environments:
  • macOS Sierra + sqlite3(ver. 3.13.0) + GEOS(ver. 3.5.0) + libspatialite(ver. 4.3.0.a). All libraries installed via Homebrew binary
  • Mac OS X 10.11, ... (the rest are the same as above).
  • Archlinux + sqlite3(ver. 3.14.2) + GEOS(ver. 3.5.0) + libspatialite(ver. 4.3.0.a). All libraries installed via official repository.
  • Then, I tried to manually compile libspatialite ver. 4.4.0-RC1 on Archlinux, the error's still there!
As you can see, 
  1. no multi_thread involved in the client codes;
  2. the 'GEOS' library is already 3.5.0 (which was said to be thread-safer).
Could you please give me some hint about what's going wrong?
I'd really appreciate your kindness!

邹鲁

unread,
Oct 5, 2016, 2:05:21 PM10/5/16
to SpatiaLite Users
and here is the backtrace:
#0  0x00007ffff6fda04f in raise () from /usr/lib/libc.so.6
#1  0x00007ffff6fdb47a in abort () from /usr/lib/libc.so.6
#2  0x00007ffff6fd2ea7 in __assert_fail_base () from /usr/lib/libc.so.6
#3  0x00007ffff6fd2f52 in __assert_fail () from /usr/lib/libc.so.6
#4  0x00007ffff5c795d8 in GEOSCoordSeq_setOrdinate_r () from /usr/lib/libgeos_c.so.1
#5  0x00007ffff737ff95 in ?? () from /usr/lib/libspatialite.so.7
#6  0x00007ffff73879e4 in gaiaIsValid () from /usr/lib/libspatialite.so.7
#7  0x0000000000401226 in main ()

邹鲁

unread,
Oct 5, 2016, 6:05:54 PM10/5/16
to SpatiaLite Users
eh, after a whole night digging deep into the source code, I've finally found the problem: adding CPPFLAGS="$CPPFLAGS -DGEOS_USE_ONLY_R_API" to ./configure:
./configure --prefix=/usr --enable-libxml2  CPPFLAGS="$CPPFLAGS -DGEOS_USE_ONLY_R_API"
By not add such a definition, the whole library won't work. And I can't find any hint on the Internet talking about this.
Since this issue occur in both Mac brew and Archlinux official repository, I thought the author might need to make some changes to the '.configure' script, or add a comment in the documentation to indicate users about it.
Anyway, thanks for making such a great library!


On Tuesday, May 10, 2016 at 3:18:00 PM UTC+8, sandro furieri wrote:

邹鲁

unread,
Oct 5, 2016, 6:42:41 PM10/5/16
to SpatiaLite Users
Oops, it turns out this workaround only apply for SpatiaLite 4.4.0-RC1. The 4.3.0a version still gives the same error, even with the added preprocessor director.

a.fu...@lqt.it

unread,
Oct 5, 2016, 7:30:52 PM10/5/16
to spatiali...@googlegroups.com
On Wed, 5 Oct 2016 15:42:41 -0700 (PDT), 邹鲁 wrote:
> Oops, it turns out this workaround only apply for SpatiaLite
> 4.4.0-RC1. The 4.3.0a version still gives the same error, even with
> the added preprocessor director.
>

Hi,

the GEOS library wasn't initially designed so to safely support
multithreading, and there was a good reason for this; at that
time GEOS was mainly intended to support PostGIS, the GeoSpatial
extension of PostgreSQL, and PostgreSQL never uses threads
(it spawns processes instead, as it was the usual Unix
programming style for many long decades).

only in recent years GEOS started implementing an alternative
API being effectively reentrant and thus threadsafe, but few
critical points still remained unsolved; finally the very
recent GEOS 3.5.0 (released on 2015-08-16) resolved any
remaining issue, and consequently GEOS 3.5.0 is the only
version of this library we can consider to be consistently
thread-safe.

SpatiaLite was necessarily forced to follow the evolution
of GEOS, and only the latest SpatiaLite 4.4.0-RC supports
the final thread-safe API implemented by GEOS 3.5.0


> eh, after a whole night digging deep into the source code, I've
> finally found the problem: adding CPPFLAGS="$CPPFLAGS
> -DGEOS_USE_ONLY_R_API" to ./configure:
>
> ./configure --prefix=/usr --enable-libxml2 CPPFLAGS="$CPPFLAGS
> -DGEOS_USE_ONLY_R_API"
>

this shouldn't be never required; the canonical ./configure script
(default settings) will always test for GEOS 3.5.0, and when this
specific version is found it will automatically trigger the
appropriate flags, this including GEOS_REENTRANT which in turns
triggers GEOS_USE_ONLY_R_API

when instead an earlier version of GEOS (< 3.5.0= is actually
found ./configure will stop by reporting the following error:
-------------------------------------------------------------
"libgeos_c' (>= v.3.5.0) is required but it doesn't seem to be
installed on this system. You may need to try re-running
configure with a --disable-geosreentrant parameter."
-------------------------------------------------------------

you can find a public announcement explaining all this stuff
in this previous post of mine:
https://groups.google.com/forum/#!searchin/spatialite-users/geosreentrant%7Csort:relevance/spatialite-users/OGjFsIYW5F0/Jhpp1FsPCgAJ

bye Sandro

邹鲁

unread,
Oct 6, 2016, 1:08:16 AM10/6/16
to SpatiaLite Users
Hi Sandro,

Thanks for such a prompt relpy.
Indeed the --enable-reentrant switch is automatically enabled when GEOS 3.5.0 is detected. But it turns out that  GEOS_REENTRANT didn't trigger GEOS_USE_ONLY_R_API in turn. As in all my test cases (libspatialite 4.3.0a & 4.4.0-RC on Mac & Linux, all with GEOS 3.5.0 installed), by not giving the GEOS_USE_ONLY_R_API definition explicitly, they all fail. I'm in good reason to suspect that.
It also important to note that the 4.3.0a version still fails even if I give it -DGEOS_USE_ONLY_R_API explicitly.


when instead an earlier version of GEOS (< 3.5.0= is actually
found ./configure will stop by reporting the following error:
-------------------------------------------------------------
"libgeos_c' (>= v.3.5.0) is required but it doesn't seem to be
installed on this system. You may need to try re-running
configure with a --disable-geosreentrant parameter."
-------------------------------------------------------------

you can find a public announcement explaining all this stuff
in this previous post of mine:
https://groups.google.com/forum/#!searchin/spatialite-users/geosreentrant%7Csort:relevance/spatialite-users/OGjFsIYW5F0/Jhpp1FsPCgAJ

And what's interesting is, as stated in your previous post, "a maximum of 64 parallel threads" is attainable even if no reentrant CPPFLAGS was given. But as you already know, all my test case failed with a fairly simple 'demo2' program, which does not spawn thread by itself, unless the spatialite library would spawn as much threads by default that exceeds the upper bound, causing a core dump.

bye Sandro

邹鲁

unread,
Oct 6, 2016, 1:27:46 AM10/6/16
to SpatiaLite Users
My guess is that GEOS_REENTRANT will indicate GEOS library to deal with functions in a thread-safe manner (triggers its GEOS_USE_ONLY_R_API mechanism), but the code base in libspatialite doesn't inherit this definition, and would still call the thread-unsafe version of functions (such as cs = GEOSCoordSeq_create (1, dims); ). The mismatching running mode between these two libraries caused the failed assertion.

I can confirm the GEOS_USE_ONLY_R_API has no effect in libspatialite, as I tried to insert the following code in src/gaiageo/gg_geoscvt.c(really brute force, because I failed to enable the debug build of libspatialite):
toGeosGeometry (const void *cache, GEOSContextHandle_t handle,

// ...
printf("[%d]\n", __LINE__); //print the line num

just before every GEOS function calls, and the output is 
[235]
That means 'GEOSCoordSeq_create (1, dims);' get called instead of 'GEOSCoordSeq_create_r (handle, 1, dims);'
(Note: the actual line number is 231. I've inserted several 'printfs' so that number becomes 235)



On Thursday, October 6, 2016 at 7:30:52 AM UTC+8, sandro furieri wrote:

a.fu...@lqt.it

unread,
Oct 6, 2016, 3:56:17 AM10/6/16
to spatiali...@googlegroups.com
On Wed, 5 Oct 2016 22:08:15 -0700 (PDT), 邹鲁 wrote:
> As in all my test cases (libspatialite 4.3.0a & 4.4.0-RC on Mac &
> Linux,
> all with GEOS 3.5.0 installed), by not giving the GEOS_USE_ONLY_R_API
> definition
> explicitly, they all fail. I'm in good reason to suspect that.
> It also important to note that the 4.3.0a version still fails even if
> I give it -DGEOS_USE_ONLY_R_API explicitly.
>

note: SpatiaLite 4.3.x was released _BEFORE_ GEOS 3.5.0, so it
could never be expected to support the latest thread-safe API
introduced in subsequent times and will simply use 3.5.0
exactly as if it was 3.4.2. or any other previous version.

if you want to activate GEOS_USE_ONLY_R_API you necessarily
have to use the most recent codebase of SpatiaLite, that is
4.4.0-RC

bye Sandro

邹鲁

unread,
Oct 6, 2016, 5:10:02 AM10/6/16
to SpatiaLite Users
But both 4.3.0a and 4.4.0-RC don't work with GEOS 3.5.0 with default 'configure', -DGESO_USE_ONLY_R_API is still needed, am I wrong?

All the best, 
- Lu

mj10777

unread,
Oct 6, 2016, 5:30:15 AM10/6/16
to SpatiaLite Users


On Thursday, 6 October 2016 11:10:02 UTC+2, 邹鲁 wrote:
But both 4.3.0a and 4.4.0-RC don't work with GEOS 3.5.0 with default 'configure', -DGESO_USE_ONLY_R_API is still needed, am I wrong?
No, with 4.4.0-RC it should work.  
You should see the following in the config.h file after ./configure

config.h:/* Should be defined in order to enable GEOS_REENTRANT (fully thread-safe). */
config.h:#define GEOS_REENTRANT 1

as Sandro explained before, when GEOS_REENTRANT 1
GESO_USE_ONLY_R_API will be used

so check what you have in your config.h file
--
When running ./configure, you should see

checking for geos-config... /usr/local/bin/geos-config
checking geos_c.h usability... yes
checking geos_c.h presence... yes
checking for geos_c.h... yes
checking for library containing GEOSCoveredBy... -lgeos_c
checking for library containing GEOSDelaunayTriangulation... none required
checking for library containing GEOSContext_setErrorMessageHandler_r... none required


look inside the '/usr/local/bin/geos-config' file 

cat /usr/local/bin/geos-config | grep '3.'
    echo 3.5.0

you should see 'echo 
3.5.0'

in that way you can be sure that geos 3.5.0 is really being used.

Mark

a.fu...@lqt.it

unread,
Oct 6, 2016, 7:23:39 AM10/6/16
to spatiali...@googlegroups.com
On Thu, 6 Oct 2016 02:30:14 -0700 (PDT), 'mj10777' via SpatiaLite Users
wrote:
> On Thursday, 6 October 2016 11:10:02 UTC+2, 邹鲁 wrote:
>
>> But both 4.3.0a and 4.4.0-RC don't work with GEOS 3.5.0 with default
>> 'configure', -DGESO_USE_ONLY_R_API is still needed, am I wrong?
>
> No, with 4.4.0-RC it should work.  
>

I can simply add that it nicely works on both Linux Debian and Fedora,
and on Windows MinGW+MSYS as well.

bye Sandro

邹鲁

unread,
Oct 6, 2016, 11:44:35 AM10/6/16
to SpatiaLite Users
Hi, Mark

All your statement are correct, expect one:  GEOS_USE_ONLY_R_API   _IS_NOT_ automatically defined (at least in libspatialite, I'm not sure about its effect on libgeos). 
To conclude my experiments (only on Archlinux & macOS):
  1. libspatialite ver. 4.3.0a has not luck with libgeos ver. 3.5.0
  2. libspatialite ver 4.4.0-RC or most recent fossil development snapshot will not work if -DGEOS_USE_ONLY_R_API is not given at configure/compile time.
I'm just stating my own experience on those two platforms. Maybe there are some specific settings that made my computers differ from the ordinary way. But all my procedures are fairly simple ones: download tarball - then compile with/without -DGEOS_USE_ONLY_R_API, and that's making whole different stories.
Also, It's very unlikely that 3 machines (2 Mac, 1 Archlinux) all suffer from strange software/environment settings -- I mean, they are just as common as any other computers running the same system. So I believe posting my experience here could help some one using same OSes like me.

BTW, one notable common feature that Mac brew and Arch share is: they both tend to use most up-to-date (rolling-updated) software packages, while as other distros like Ubuntu or Fedora tend to use relatively old but stable ones.

Thanks, all guys!
-- Lu

Thanks to 


On Thursday, October 6, 2016 at 5:30:15 PM UTC+8, mj10777 wrote:


On Thursday, 6 October 2016 11:10:02 UTC+2, 邹鲁 wrote:
But both 4.3.0a and 4.4.0-RC don't work with GEOS 3.5.0 with default 'configure', -DGESO_USE_ONLY_R_API is still needed, am I wrong?
No, with 4.4.0-RC it should work.  
You should see the following in the config.h file after ./configure

config.h:/* Should be defined in order to enable GEOS_REENTRANT (fully thread-safe). */
config.h:#define GEOS_REENTRANT 1
"GEOS_REENTRANT 1" : YES
as Sandro explained before, when GEOS_REENTRANT 1
GESO_USE_ONLY_R_API will be used
 "GESO_USE_ONLY_R_API will be used" : NO
As I stated before, this directive does not take effect in libspatialite, unless -DGESO_USE_ONLY_R_API is explicitly given.


so check what you have in your config.h file
--
When running ./configure, you should see

checking for geos-config... /usr/local/bin/geos-config
checking geos_c.h usability... yes
checking geos_c.h presence... yes
checking for geos_c.h... yes
checking for library containing GEOSCoveredBy... -lgeos_c
checking for library containing GEOSDelaunayTriangulation... none required
checking for library containing GEOSContext_setErrorMessageHandler_r... none required


 
look inside the '/usr/local/bin/geos-config' file 

cat /usr/local/bin/geos-config | grep '3.'
    echo 3.5.0

you should see 'echo 
3.5.0'
 'echo 3.5.0': YES

a.fu...@lqt.it

unread,
Oct 6, 2016, 2:10:51 PM10/6/16
to spatiali...@googlegroups.com
On Thu, 6 Oct 2016 08:44:34 -0700 (PDT), 邹鲁 wrote:
> Hi, Mark
>
> All your statement are correct, expect one:  GEOS_USE_ONLY_R_API  
> _IS_NOT_ automatically defined (at least in libspatialite, I'm not
> sure about its effect on libgeos).
>

Hi Lu,

GEOS_USE_ONLY_R_API has absolutely no effect on GEOS, it's a flag
internal to SpatiaLite only.
when declared it simply causes the complete sterilization of any
internal wrapping function based on the old (non-reentrant) GEOS API,
thar will then skip the function body immediately returning an error
(usually a NULL).

example #1:
-----------
if GEOS_USE_ONLY_R_API is _NOT_ defined a C/C++ developer can
freely choose (under his/her responsibility) to call either
gaiaGeometryUnion_r() - reentrant function
or
gaiaGeometryUnion() - old-style, non-reentrant function

example #2:
-----------
if GEOS_USE_ONLY_R_API is effectively defined a C/C++ developer
will be forcibly forbidden to call the non-reentrant
gaiaGeometryUnion(),
because this function will always return a NULL value and will
not call GEOS at all.

it should be now clear why GEOS_USE_ONLY_R_API is not enabled by
default; it's only an extravagant internal setting that doesn't
adds a bit to the codebase of libspatialite, it simply disables
half of the GEOS-related internal wrappers (all the ones based
on the old non-reentrant API).

all this considered, it looks not very credible that defining
GEOS_USE_ONLY_R_API could sanitize in any way libspatialite or
GEOS; it will more probably cause lots of invalid results.
the real cause of your issues is still to be identified, and
GEOS_USE_ONLY_R_API probably is just a red herring [1].

[1] https://en.wikipedia.org/wiki/Red_herring

bye Sandro

邹鲁

unread,
Oct 6, 2016, 4:04:04 PM10/6/16
to SpatiaLite Users
Hi Sandro,
Thank you for such a detailed explanation.

I've checked the GEOS' web site, it's changelog of 3.5.0 suggests " - GEOS_USE_ONLY_R_API macro support (#695)" is there.
Ref: https://trac.osgeo.org/geos/browser/tags/3.5.0/NEWS

Indeed, this macro should only affects libspatialite. Now I do believe it had some impact on libspatialite, namely returning NULL for non-reentrant functions as evidented in the backtrace. But the problem is that the user ('demo2' in this case) didn't invoke any high level function. It just invoked 'gaiaIsValid()'. It's the library itself that invoked toGeosGeometry(). the internal variable 'cs' is set to NULL and get passed to GEOS, which rosed the assertion failure.

I do see some definitions like '#ifndef GEOS_USE_ONLY_R_API ... some_func() ... #else ... some_func_r()'. It's inside the 'gg_geoscvt.c'. And I have proved that the non-reentrant branch got selected. That's why I thought the macro didn't take effect.

So here is the controversy: if the macro made non-reentrant functions return NULL, why it didn't make toGeosGeometry() to select the correct functions that are reentrant?
Or maybe I should invoke something like gaiaIsValid_r() instead?

Apologies if I spelled some names inaccurately, cause I don't have access to my computer right now.

Best wishes!

--Lu

Reply all
Reply to author
Forward
0 new messages