Skip to content

Commit

Permalink
Merge pull request #2794 from vibe-d/issue_2793_mongocursor_memory_op…
Browse files Browse the repository at this point in the history
…eration_error

Avoid possible GC allocations in MongoCursor.~this
  • Loading branch information
s-ludwig authored Mar 26, 2024
2 parents 7ea145c + da4b61d commit f10ce9b
Showing 1 changed file with 22 additions and 8 deletions.
30 changes: 22 additions & 8 deletions mongodb/vibe/db/mongo/cursor.d
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,21 @@ struct MongoCursor(DocType = Bson) {

~this() @safe
{
if( m_data && --m_data.refCount == 0 ){
try {
m_data.killCursors();
} catch (MongoException e) {
logWarn("MongoDB failed to kill cursors: %s", e.msg);
logDiagnostic("%s", (() @trusted => e.toString)());
import core.memory : GC;

if (m_data && --m_data.refCount == 0) {
if (m_data.alive) {
// avoid InvalidMemoryOperation errors in case the cursor was
// leaked to the GC
if(GC.inFinalizer) {
logError("MongoCursor instance that has not been fully processed leaked to the GC!");
} else {
try m_data.killCursors();
catch (MongoException e) {
logWarn("MongoDB failed to kill cursors: %s", e.msg);
logDiagnostic("%s", (() @trusted => e.toString)());
}
}
}
}
}
Expand Down Expand Up @@ -288,6 +297,7 @@ struct MongoCursor(DocType = Bson) {
/// interface because we still have code for legacy (<3.6) MongoDB servers,
/// which may still used with the old legacy overloads.
private interface IMongoCursorData(DocType) {
@property bool alive() @safe nothrow;
bool empty() @safe; /// Range implementation
long index() @safe; /// Range implementation
DocType front() @safe; /// Range implementation
Expand Down Expand Up @@ -326,6 +336,8 @@ private deprecated abstract class LegacyMongoCursorData(DocType) : IMongoCursorD
long m_limit = 0;
}

@property bool alive() @safe nothrow { return m_cursor != 0; }

final bool empty()
@safe {
if (!m_iterationStarted) startIterating();
Expand Down Expand Up @@ -390,8 +402,8 @@ private deprecated abstract class LegacyMongoCursorData(DocType) : IMongoCursorD

final void killCursors()
@safe {
auto conn = m_client.lockConnection();
if (m_cursor == 0) return;
auto conn = m_client.lockConnection();
conn.killCursors(m_collection, () @trusted { return (&m_cursor)[0 .. 1]; } ());
m_cursor = 0;
}
Expand Down Expand Up @@ -448,6 +460,8 @@ private class MongoFindCursor(DocType) : IMongoCursorData!DocType {
m_database = command["$db"].opt!string;
}

@property bool alive() @safe nothrow { return m_cursor != 0; }

bool empty()
@safe {
if (!m_iterationStarted) startIterating();
Expand Down Expand Up @@ -515,8 +529,8 @@ private class MongoFindCursor(DocType) : IMongoCursorData!DocType {

final void killCursors()
@safe {
auto conn = m_client.lockConnection();
if (m_cursor == 0) return;
auto conn = m_client.lockConnection();
conn.killCursors(m_ns, () @trusted { return (&m_cursor)[0 .. 1]; } ());
m_cursor = 0;
}
Expand Down

0 comments on commit f10ce9b

Please sign in to comment.