Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid possible GC allocations in MongoCursor.~this #2794

Merged
merged 3 commits into from
Mar 26, 2024

Conversation

s-ludwig
Copy link
Member

This adds a check to the destructor to avoid running into an InvalidMemoryOperationError and instead outputs a more descriptive error message without crashing. This also swaps back the order of operations in killCursors() so that no connection to the server gets allocated by the call if the cursor has already been killed.

Fixes #2793.

This adds a check to the destructor to avoid running into an InvalidMemoryOperationError and instead outputs a more descriptive error message without crashing. This also swaps back the order of operations in killCursors() so that no connection to the server gets allocated by the call if the cursor has already been killed.
// leaked to the GC
if(GC.inFinalizer) {
logError("MongoCursor instance that has not been fully processed leaked to the GC!");
try throw new Exception("");
Copy link
Contributor

Choose a reason for hiding this comment

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

this is an allocation, is this even reliable? Might need to check the ABI docs here

Copy link
Member Author

Choose a reason for hiding this comment

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

Oops, you are right of course, that won't work, I didn't really think there. Unfortunate that we don't have @nogc stack trace code in DRuntime. I do have an implementation for a different project, maybe it makes sense to publish that on code.dlang.org.

Copy link
Contributor

Choose a reason for hiding this comment

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

so I'm not even sure if the definition is exactly not to allocate in a destructor, since it's not listed in the spec: https://dlang.org/spec/class.html#destructors

however it says not to use child data - unsure how it's supposed to work with cyclic things

Copy link
Member Author

Choose a reason for hiding this comment

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

The reality with the GC is that finalizers (or struct destructors in that situation) are only (safely) usable for very simple things (calling free() or close()). It's also not just child data, but also any GC allocated memory that poses a problem (i.e. data referenced by static variables). I'm not sure if or where it's mentioned in the spec, but the implementation will error out for any GC action you invoke from within a finalizer call.

While some of this could definitely improved in the GC, I think the only realistic way to avoid issues like this is to make eventcore and the relevant parts of vibe-core fully @nogc.

BTW, another serious shortcoming with the current GC is that you also may only do thread-safe things, so even something like glDeleteTextures() is not an option, and since finalizers are running in parallel to application code, I bet that there are many race-conditions hidden in real-world finalizers.

@s-ludwig s-ludwig merged commit f10ce9b into master Mar 26, 2024
58 checks passed
@s-ludwig s-ludwig deleted the issue_2793_mongocursor_memory_operation_error branch March 26, 2024 05:48
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.

Error on creating a mongo connection
2 participants