[CXX-840] Infinite wait in mongo 1.0.7 client if mongo::client::shutdown not explicitly called Created: 09/Feb/16 Updated: 23/Mar/16 Resolved: 23/Mar/16 |
|
| Status: | Closed |
| Project: | C++ Driver |
| Component/s: | Implementation |
| Affects Version/s: | legacy-1.0.3, legacy-1.0.7 |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Steve Ahlgren | Assignee: | Mira Carey |
| Resolution: | Incomplete | Votes: | 0 |
| Labels: | legacy-cxx | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Attachments: |
|
| Description |
|
Hi All, Since updating from 2.x to 3.x, we've experienced significant difficultly with the new client driver requiring the explicit calls to mongo::client::initialize and mongo::client::shutdown, with a fatal infinite wait in the replica set monitor watcher if mongo::client::shutdown is not called explicitly. We use Mongo in a shared library (dll) that is consumed by a number of clients, and in this scenario it's not straightforward to call mongo::client::shutdown from the parent executable. When the executable dies and the mongo wrapper DLL unloads, the mongo client driver's threads are terminated before the destructor for the replica set monitor watcher is called. When its destructor is called, it waits on a condition variable that will never be set, as the thread is already gone. There are several possible workarounds and refactoring that could happen in the client driver. But the main question is what's the best practice for wrapping the new Mongo driver in a dll used by a number of consumers? The current driver implementation makes this difficult if not impossible, so any advice would be appreciated. An example app package is attached showing an exe calling a dll containing Mongo functionality. Thank you kindly in advance, |
| Comments |
| Comment by Andrew Morrow (Inactive) [ 19/Mar/16 ] | |||||||||
|
Hi sga - Is there anything further we can help you with regarding this ticket? If so, please let us know, otherwise we will close this out. | |||||||||
| Comment by Andrew Morrow (Inactive) [ 20/Feb/16 ] | |||||||||
|
Hi sga - I'd like to better understand the issue you are having and why DLLs are problematic for you. I'm not at all as familiar with the mechanics of DLLs as I am with ELF shared objects, and I'm sort of reasoning by analogy with those, so apologies if I've got something wrong - I'm not a Windows expert, really. I would expect that during process teardown destructors for objects of file scope in a DLL are executed. I would also expect that if foo.dll depends on bar.dll, that the destruction of global objects in bar.dll would be sequenced before the destruction of global objects in foo.dll. So, we have three things in play, really: the application (lets call it app.exe), the DLL that uses mongoclient.dll (lets call it user.dll), and we have the mongoclient.dll itself. I'm imagining that app.exe depends on user.dll, which in turn depends on mongoclient.dll. I would imagine that it a file, call it user.cpp, that was compiled into user.dll contained the following code
That when app.exe terminated, the destructor of instance above would be sequenced before the termination of mongoclient.dll. Would something like that not work? | |||||||||
| Comment by Steve Ahlgren [ 09/Feb/16 ] | |||||||||
|
Hi Jason, Thank you for the quick response. We will definitely consider the new driver. Best, | |||||||||
| Comment by Mira Carey [ 09/Feb/16 ] | |||||||||
|
Steve, As you've noted, the legacy C++ driver isn't very amenable to wrapping. This is a natural consequence of how it came to be; as a series of improvements to code lifted directly out of the main mongodb source code. Unfortunately, that's also unlikely to change, as the legacy driver is no longer under active feature development and new feature support will be focused in our new C++11 driver. If you're looking for a best practice to wrap up a connection to mongodb in a dll, I'd recommend that you consider our new C++11 driver, or its backend implementation (libmongoc). The C++11 driver offers a modern interface and the promise of future support, while the C driver offers a barebones implementation and a commitment to a stable ABI. While there is a notion of a global instance for our new C++ driver, and an init() / cleanup() pair for the c driver, they manage far more simplistic initialization and don't own anything like a background thread. Regards, |