Skip to content

Conversation

@eramongodb
Copy link
Contributor

@eramongodb eramongodb commented Aug 6, 2025

Resolves CXX-3324 by removing all use of mongocxx::v_noabi::instance::current() except in src/mongocxx/test/v_noabi/instance.cpp (to preserve some test coverage of this API until its removal).

The current() function was added to mongocxx::v_noabi::instance a long time ago by #441 (Jan 2016) to address ASAN and Valgrind memory leak errors. #513 (Sep 2016) later added the clarification that current() is "intended primarily for test authors". At this time, Catch was a header-only library, specifically the "CATCH v1.0 build 53 (master branch)" header generated on August 2014. This version predates the first ever stable release by nearly a year. The header was updated to v1.9.4 on June 2017, to v2.2.1 on April 2018, then to v3.7.0 on September 2024. That is to say, the codebase has changed quite a lot since current() was added.

#1202 added a catch.cpp file providing a user-defined main() function as part of __cdecl checks on Windows (to avoid the Catch2-supplied main() from incorrectly inheriting the non-cdecl default calling convention). This main() function is the perfect place to create the mongocxx::v_noabi::instance object for subsequent use by the test suite. The only exceptions are the test_instance and test_logging executables which need to create their own instance object to test mongocxx::v_noabi::instance itself. All other cases of calling current() function is made obsolete, and therefore, removed by this PR.

Note

This is similar in spirit to the API examples runner creating a mongocxx::instance object prior to executing non-forking components.

It is premature to remove current() entirely, given it's been present in both the publically-documented API and ABI for a very long time (there are almost certainly users depending on it despite the "intended primarily for test authors" note). However, a deprecation note has been added to CHANGELOG declaring its new "for internal use only" documentation. AFAICT there is no reason to continue supporting the current() function as part of the public API aside from its "initialize if not already initialized" behavior (which was really only ever meant to be used for testing purposes), as there is no reason to obtain the "current" instance object for any subsequent purpose (the instance class has no meaningful API beyond its constructors + SMFs).

Note

CXX-1029 proposes adding API to the instance class to support inspecting and modifying library logging behavior in addition to mongocxx (and mongoc) library initialization and cleanup. We can consider re-introducing a current() function alongside such logging-related API, likely as an extension to the v1 API rather than to the v_noabi API.

After this PR, the only remaining use of the current() function is in instance.cpp to preserve test coverage of the function until it is ultimately removed in an upcoming API major version release. (The tests were also fixed to avoid assuming test-case-declaration execution order.) The MONGOCXX_TEST_DISABLE_MAIN_INSTANCE preprocessor macro is defined when building the test_instance and test_logging test executables to disable the creation of an instance object in main(); all other mongocxx test executables create an instance object in main() prior to invoking the Catch2 test runner.

@eramongodb eramongodb requested a review from kevinAlbs August 6, 2025 20:54
@eramongodb eramongodb self-assigned this Aug 6, 2025
@eramongodb eramongodb requested a review from a team as a code owner August 6, 2025 20:54
Copy link
Collaborator

@kevinAlbs kevinAlbs left a comment

Choose a reason for hiding this comment

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

Changes look good. I vote for leaving instance::current un-deprecated.


### Deprecated

- `mongocxx::v_noabi::instance::current()` is "for internal use only". The `instance` constructor(s) should be used instead.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I see usage of instance::current() in GitHub code search. I suspect it might be useful to conditionally initialize the C++ driver on first use (for example in an extension).

Is there much harm in keeping instance::current()? If there are multiple users, I would rather leave it un-deprecated.

Copy link
Contributor Author

@eramongodb eramongodb Aug 8, 2025

Choose a reason for hiding this comment

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

Is there much harm in keeping instance::current()?

The motivation is to discourage usage patterns which require global state (e.g. see CDRIVER-1547; I don't think we have a C++ Driver equivalent ticket yet). The behavior of instance::current() is fundamentally global (the function static local variable is an implementation detail). By deprecating and removing this function, users will be forced to explicitly decide their instance object allocation strategy; they have to create an instance object somewhere. This will ultimately provide us with better opportunities to remove global state (by moving state into the instance object) while preserving global mongoc initialization/cleanup behavior internally rather than via a dedicated API (that is, we reduce the scope of the current global atomic variable to handling one-time mongoc init/cleanup only, per CXX-1029, until mongoc also hopefully/eventually removes its global state requirements).

The code search results appear to support the case that most users can easily substitute mongocxx::instance::current(); with static mongocxx::instance current;, as all the projects appear to have only one substantial call to current() within their the codebase (that is not test or example code).

Copy link
Collaborator

Choose a reason for hiding this comment

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

most users can easily substitute mongocxx::instance::current(); with static mongocxx::instance current;

Good point. Suggest expanding the changelog entry to help users migrate. Example:

If an application only calls mongocxx::instance::current(); once, it can likely be replaced with static mongocxx::instance current;:

// Before:
void handler () {
    mongocxx::instance::current();
    // ... code using mongocxx ...
}
// After:
void handler () {
    static mongocxx::instance current;
    // ... code using mongocxx ...
}

@eramongodb eramongodb requested a review from kevinAlbs August 8, 2025 18:29

### Deprecated

- `mongocxx::v_noabi::instance::current()` is "for internal use only". The `instance` constructor(s) should be used instead.
Copy link
Collaborator

Choose a reason for hiding this comment

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

most users can easily substitute mongocxx::instance::current(); with static mongocxx::instance current;

Good point. Suggest expanding the changelog entry to help users migrate. Example:

If an application only calls mongocxx::instance::current(); once, it can likely be replaced with static mongocxx::instance current;:

// Before:
void handler () {
    mongocxx::instance::current();
    // ... code using mongocxx ...
}
// After:
void handler () {
    static mongocxx::instance current;
    // ... code using mongocxx ...
}

@eramongodb eramongodb merged commit aa8850b into mongodb:master Aug 8, 2025
1 of 2 checks passed
@eramongodb eramongodb deleted the cxx-3324 branch August 8, 2025 21:08
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.

2 participants