Skip to content

Split MEOS initialisation in MeosThread into process-once and per-thread - #43

Merged
estebanzimanyi merged 1 commit into
MobilityDB:mainfrom
estebanzimanyi:fix/meosthread-layered-init
Jul 23, 2026
Merged

Split MEOS initialisation in MeosThread into process-once and per-thread#43
estebanzimanyi merged 1 commit into
MobilityDB:mainfrom
estebanzimanyi:fix/meosthread-layered-init

Conversation

@estebanzimanyi

Copy link
Copy Markdown
Member

MeosThread initialises MEOS by running the full meos_initialize() on every executor thread. That is unsafe under concurrency: meos_initialize() re-installs the process-global error handler (MEOS's exiting default), so one thread's initialisation momentarily replaces the no-exit handler that every other thread relies on to turn a MEOS error into a Java exception. A MEOS error raised in that window ends the JVM with exit(EXIT_FAILURE) — silently, with no stack trace.

MEOS setup has two lifetimes:

  • process-global — the allocator and the error handler;
  • thread-local — the timezone and collation caches; the PROJ, GEOS and GSL contexts are thread-local too and are created lazily by MEOS on first use (proj_get_context/geos_get_context call the static per-thread initialisers on demand).

This change installs the process-global part once per JVM through a holder whose class initialiser runs under the JVM class-initialisation lock, and runs only meos_initialize_timezone + meos_initialize_collation per thread. No thread re-installs the handler, so the reset window is closed; PROJ/GEOS/GSL still initialise lazily per thread, so spatial UDFs are unaffected.

ensureReady() is unchanged, so every generated UDF entry point still guards correctly.

MeosThread ran the full meos_initialize() on every executor thread. That
is unsafe: meos_initialize() re-installs the process-global error handler
(MEOS's exiting default), so one thread's initialisation momentarily
replaces the no-exit handler that every other thread relies on to turn a
MEOS error into a Java exception. A MEOS error raised in that window ends
the JVM with exit(EXIT_FAILURE).

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, and run only meos_initialize_timezone and meos_initialize_collation
per thread. No thread re-installs the handler, so the window is closed.
@estebanzimanyi
estebanzimanyi merged commit 64954cd into MobilityDB:main Jul 23, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant