Skip to content

Commit aa8850b

Browse files
authored
CXX-3324 remove all use of instance::current() (#1438)
* Document recommendations and workarounds for replacing current() in user code
1 parent ea5cb6a commit aa8850b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+42
-448
lines changed

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,26 @@ Changes prior to 3.9.0 are documented as [release notes on GitHub](https://githu
2525
- Apple Clang 13.1 with Xcode 13.4.1 (from Apple Clang 5.1 with Xcode 5.1).
2626
- MSVC 19.0.24210 with Visual Studio 2015 Update 3 (from MSVC 19.0.23506 with Visual Studio 2015 Update 1).
2727

28+
### Deprecated
29+
30+
- `mongocxx::v_noabi::instance::current()` is "for internal use only". The `instance` constructor(s) should be used instead.
31+
- Creating the `instance` object in the scope of `main()`, or in an appropriate (non-global) scope such that its (non-static) lifetime is valid for the duration of all other mongocxx library operations, is recommended over the following workarounds.
32+
- If there is only _one_ call to `current()` present within an application, it may be replaced with a static local variable:
33+
```cpp
34+
// Before:
35+
mongocxx::instance::current();
36+
37+
// After:
38+
static mongocxx::instance instance; // Only ONE instance object!
39+
```
40+
- If there are _multiple_ calls to `current()` present within an application, they may be replaced with a call to a user-defined function containing the static local variable:
41+
```cpp
42+
mongocxx::instance& mongocxx_instance() {
43+
static mongocxx::instance instance; // Only ONE instance object!
44+
return instance;
45+
}
46+
```
47+
2848
### Removed
2949

3050
- Support for MongoDB Server 4.2.

docs/api/mongocxx/examples/instance.md

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,6 @@
44

55
@snippet api/mongocxx/examples/instance/basic_usage.cpp Example
66

7-
## With Static Lifetime
8-
9-
@warning This pattern depends on an exit-time destructor with indeterminate order relative to other objects with static lifetime being destroyed.
10-
11-
@snippet api/mongocxx/examples/instance/current.cpp Example
12-
137
# Errors
148

159
## Instance Recreation

examples/api/mongocxx/examples/instance/basic_usage.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ void example() {
3232
// Initialize the MongoDB C++ Driver by constructing the instance object.
3333
mongocxx::instance instance;
3434

35-
EXPECT(&mongocxx::instance::current() == &instance);
36-
3735
// Use mongocxx library interfaces at this point.
3836
use(mongocxx::client{});
3937

examples/api/mongocxx/examples/instance/current.cpp

Lines changed: 0 additions & 53 deletions
This file was deleted.

examples/api/mongocxx/examples/instance/destroyed.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ void example() {
3737
}
3838

3939
try {
40-
auto& instance = mongocxx::instance::current(); // Throws.
40+
mongocxx::instance instance; // Throws.
4141

4242
EXPECT(false && "should not reach this point");
4343
} catch (mongocxx::exception const& ex) {
44-
EXPECT(ex.code() == mongocxx::error_code::k_instance_destroyed);
44+
EXPECT(ex.code() == mongocxx::error_code::k_cannot_recreate_instance);
4545
}
4646
}
4747
// [Example]

examples/api/mongocxx/examples/instance/recreation.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,13 @@ void example() {
2626
{
2727
mongocxx::instance instance;
2828

29-
EXPECT(&mongocxx::instance::current() == &instance);
30-
3129
try {
3230
mongocxx::instance another_instance; // Throws.
3331

3432
EXPECT(false && "should not reach this point");
3533
} catch (mongocxx::exception const& ex) {
3634
EXPECT(ex.code() == mongocxx::error_code::k_cannot_recreate_instance);
3735
}
38-
39-
EXPECT(&mongocxx::instance::current() == &instance);
4036
}
4137
}
4238
// [Example]

src/mongocxx/include/mongocxx/v_noabi/mongocxx/instance.hpp

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -111,19 +111,7 @@ class instance {
111111
instance& operator=(instance const&) = delete;
112112

113113
///
114-
/// Returns the current unique instance of the driver. If an instance was explicitly created,
115-
/// that will be returned. If no instance has yet been created, a default instance will be
116-
/// constructed and returned. If a default instance is constructed, its destruction will be
117-
/// sequenced according to the rules for the destruction of static local variables at program
118-
/// exit (see http://en.cppreference.com/w/cpp/utility/program/exit).
119-
///
120-
/// Note that, if you need to configure the instance in any way (e.g. with a logger), you cannot
121-
/// use this method to cause the instance to be constructed. You must explicitly create an
122-
/// properly configured instance object. You can, however, use this method to obtain that
123-
/// configured instance object.
124-
///
125-
/// @note This method is intended primarily for test authors, where managing the lifetime of the
126-
/// instance w.r.t. the test framework can be problematic.
114+
/// @warning For internal use only!
127115
///
128116
static MONGOCXX_ABI_EXPORT_CDECL(instance&) current();
129117

src/mongocxx/test/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,10 @@ add_executable(test_driver
137137
target_link_libraries(test_driver PRIVATE spec_test_common client_helpers)
138138

139139
add_executable(test_logging v_noabi/logging.cpp)
140+
target_compile_definitions(test_logging PRIVATE MONGOCXX_TEST_DISABLE_MAIN_INSTANCE)
140141

141142
add_executable(test_instance v_noabi/instance.cpp)
143+
target_compile_definitions(test_instance PRIVATE MONGOCXX_TEST_DISABLE_MAIN_INSTANCE)
142144

143145
add_executable(test_crud_specs spec/crud.cpp)
144146
target_link_libraries(test_crud_specs PRIVATE spec_test_common client_helpers)

src/mongocxx/test/catch.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,14 @@
1414

1515
#include <mongocxx/v1/config/export.hpp>
1616

17+
#include <mongocxx/instance.hpp>
18+
1719
#include <catch2/catch_session.hpp>
1820

1921
int MONGOCXX_ABI_CDECL main(int argc, char* argv[]) {
22+
#if defined(MONGOCXX_TEST_DISABLE_MAIN_INSTANCE)
2023
return Catch::Session().run(argc, argv);
24+
#else
25+
return ((void)mongocxx::instance(), Catch::Session().run(argc, argv));
26+
#endif
2127
}

src/mongocxx/test/private/write_concern.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ using namespace mongocxx;
2626
TEST_CASE(
2727
"creation of write_concern passes universal parameters to c-driver's methods",
2828
"[write_concern][base][c-driver]") {
29-
instance::current();
30-
3129
SECTION("when journal is requested, mongoc_write_concern_set_journal is called with true") {
3230
bool journal_called = false;
3331
bool journal_value = false;
@@ -60,8 +58,6 @@ TEST_CASE(
6058
}
6159

6260
TEST_CASE("write_concern is called with w MAJORITY", "[write_concern][base][c-driver]") {
63-
instance::current();
64-
6561
bool w_called = false, wmajority_called = false, wtag_called = false;
6662
auto w_instance = libmongoc::write_concern_set_w.create_instance();
6763
auto wmajority_instance = libmongoc::write_concern_set_wmajority.create_instance();
@@ -88,8 +84,6 @@ TEST_CASE("write_concern is called with w MAJORITY", "[write_concern][base][c-dr
8884
}
8985

9086
TEST_CASE("write_concern is called with a number of necessary confirmations", "[write_concern][base][c-driver]") {
91-
instance::current();
92-
9387
bool w_called = false, wmajority_called = false, wtag_called = false;
9488
int w_value = 0;
9589
int const expected_w = 5;
@@ -122,8 +116,6 @@ TEST_CASE("write_concern is called with a number of necessary confirmations", "[
122116
}
123117

124118
TEST_CASE("write_concern is called with a tag", "[write_concern][base][c-driver]") {
125-
instance::current();
126-
127119
bool w_called = false, wmajority_called = false, wtag_called = false;
128120
std::string wtag_value;
129121
std::string const expected_wtag("MultiDataCenter");

0 commit comments

Comments
 (0)