Skip to content

Initialize JSON schemas lazily to avoid static initialization order issue - #3

Merged
massis08 merged 1 commit into
bisectfrom
ma/dev/c-locale-abort
Oct 7, 2026
Merged

massis08 merged 1 commit into
bisectfrom
ma/dev/c-locale-abort

Conversation

@massis08

@massis08 massis08 commented Oct 6, 2026 •

Copy link
Copy Markdown

Reasoning

nmos::details::schemas was a namespace-scope static built during static initialization by make_schemas(), which parses the bundled JSON schemas with cpprestsdk.

cpprestsdk's JSON parser uses scoped_c_thread_locale, and scoped_c_thread_locale::c_locale() depends on cpprestsdk's own static globals. C++ doesn't guarantee initialization order across translation units or shared libraries, so the schemas can be parsed before cpprestsdk is ready. This shows up when nmos-cpp is loaded with dlopen while the process locale is not "C": the locale path in cpprestsdk is taken, and it uses state that hasn't been initialized yet.

Explanation

  • Replaced the namespace-scope schemas map with a schemas() function that holds a function-local static. The map is now built on the first call, after static initialization has finished. Since C++11, function-local statics are initialized in a thread-safe way.
  • Updated load_json_schema() to call schemas(). Its behaviour is unchanged: it still throws json_exception when a schema ID isn't found.
  • The schemas are now parsed on first use rather than at startup, so loading the library no longer parses JSON. The first schema lookup does that work instead.

🤖 Generated with Claude Code

@LufeBisect

The schema map was built during static initialization, which parses JSON via cpprestsdk. cpprestsdk's scoped_c_thread_locale::c_locale() is not safe to call before cpprestsdk's own globals are initialized, e.g. when
the library is dlopen'ed while the process locale is not "C".

Replace the static map with a function-local static so the schemas are built on first call to load_json_schema().

@pedro-alves-ferreira pedro-alves-ferreira left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@massis08
massis08 merged commit e44468c into bisect Oct 7, 2026
20 checks passed
@massis08
massis08 deleted the ma/dev/c-locale-abort branch October 7, 2026 14:04
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.

3 participants