Split MEOS initialisation in MEOSBridge into process-once and per-thread - #24
Merged
estebanzimanyi merged 1 commit intoJul 23, 2026
Conversation
MEOSBridge initialised MEOS on each stream thread by installing a no-exit error handler and then calling the full meos_initialize(). That order also defeats the handler: meos_initialize() re-installs MEOS's exiting default handler, so the no-exit handler never takes effect and any MEOS error ends the JVM with exit(EXIT_FAILURE). Running meos_initialize() per thread is unsafe regardless, because the handler is process-global — one thread's initialisation replaces the handler every other thread relies on. MEOS setup has two lifetimes: the allocator and error handler are process-global, while the timezone and collation caches are thread-local (the PROJ, GEOS and GSL contexts are thread-local too and created lazily on first use). Install the process-global part once per JVM through a holder whose class initialiser runs under the JVM class-initialisation lock — meos_initialize() first, then the no-exit handler — and run only meos_initialize_timezone and meos_initialize_collation per thread. The no-exit handler now stands, and no thread re-installs it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
MEOSBridge initialises MEOS on each stream thread by installing a no-exit error handler and then calling the full
meos_initialize(). Two problems follow:meos_initialize()re-installs MEOS's exiting default handler, so calling it after the no-exit handler discards the no-exit handler — every thread ends with the exiting default, and any MEOS error ends the JVM withexit(EXIT_FAILURE).meos_initialize()per thread means one thread's initialisation replaces the handler every other thread relies on.MEOS setup has two lifetimes:
This change installs the process-global part once per JVM through a holder whose class initialiser runs under the JVM class-initialisation lock —
meos_initialize()first, then the no-exit handler, so the no-exit handler stands — and runs onlymeos_initialize_timezone+meos_initialize_collationper thread. PROJ/GEOS/GSL still initialise lazily per thread, so the spatial predicates are unaffected.This mirrors the same fix in MobilitySpark (
MeosThread).