summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/catalog/cursor_manager.cpp27
-rw-r--r--src/mongo/db/catalog/cursor_manager.h2
-rw-r--r--src/mongo/db/clientcursor.cpp6
-rw-r--r--src/mongo/db/clientcursor.h4
-rw-r--r--src/mongo/db/range_preserver.h2
5 files changed, 25 insertions, 16 deletions
diff --git a/src/mongo/db/catalog/cursor_manager.cpp b/src/mongo/db/catalog/cursor_manager.cpp
index 8597f410dd6..aea0310fe90 100644
--- a/src/mongo/db/catalog/cursor_manager.cpp
+++ b/src/mongo/db/catalog/cursor_manager.cpp
@@ -205,10 +205,13 @@ namespace mongo {
}
}
- if (ns == globalCursorManager->ns()) {
+ // If this cursor is owned by the global cursor manager, ask it to erase the cursor for us.
+ if (globalCursorManager->ownsCursorId(id)) {
return globalCursorManager->eraseCursor(txn, id, checkAuth);
}
+ // If not, then the cursor must be owned by a collection. Erase the cursor under the
+ // collection lock (to prevent the collection from going away during the erase).
AutoGetCollectionForRead ctx(txn, nss);
if (!ctx.getDb()) {
return false;
@@ -227,21 +230,29 @@ namespace mongo {
}
std::size_t GlobalCursorIdCache::timeoutCursors(OperationContext* txn, int millisSinceLastCall) {
+ size_t totalTimedOut = 0;
+
+ // Time out the cursors from the global cursor manager.
+ totalTimedOut += globalCursorManager->timeoutCursors( millisSinceLastCall );
+
+ // Compute the set of collection names that we have to time out cursors for.
vector<string> todo;
{
SimpleMutex::scoped_lock lk( _mutex );
- for ( Map::const_iterator i = _idToNS.begin(); i != _idToNS.end(); ++i )
+ for ( Map::const_iterator i = _idToNS.begin(); i != _idToNS.end(); ++i ) {
+ if (globalCursorManager->ownsCursorId(cursorIdFromParts(i->first, 0))) {
+ // Skip the global cursor manager, since we handle it above (and it's not
+ // associated with a collection).
+ continue;
+ }
todo.push_back( i->second );
+ }
}
- size_t totalTimedOut = 0;
-
+ // For each collection, time out its cursors under the collection lock (to prevent the
+ // collection from going away during the erase).
for ( unsigned i = 0; i < todo.size(); i++ ) {
const std::string& ns = todo[i];
- if ( ns == globalCursorManager->ns() ) {
- totalTimedOut += globalCursorManager->timeoutCursors( millisSinceLastCall );
- continue;
- }
AutoGetCollectionForRead ctx(txn, ns);
if (!ctx.getDb()) {
diff --git a/src/mongo/db/catalog/cursor_manager.h b/src/mongo/db/catalog/cursor_manager.h
index 3f92e8eaf69..5c5619c5ebb 100644
--- a/src/mongo/db/catalog/cursor_manager.h
+++ b/src/mongo/db/catalog/cursor_manager.h
@@ -56,8 +56,6 @@ namespace mongo {
// -----------------
- std::string ns() { return _nss.ns(); }
-
/**
* @param collectionGoingAway Pass as true if the Collection instance is going away.
* This could be because the db is being closed, or the
diff --git a/src/mongo/db/clientcursor.cpp b/src/mongo/db/clientcursor.cpp
index 356e25182bb..a98867d6291 100644
--- a/src/mongo/db/clientcursor.cpp
+++ b/src/mongo/db/clientcursor.cpp
@@ -90,9 +90,9 @@ namespace mongo {
init();
}
- ClientCursor::ClientCursor(CursorManager* cursorManager)
- : _ns(cursorManager->ns()),
- _cursorManager(cursorManager),
+ ClientCursor::ClientCursor(const Collection* collection)
+ : _ns(collection->ns().ns()),
+ _cursorManager(collection->cursorManager()),
_countedYet(false),
_queryOptions(QueryOption_NoCursorTimeout),
_isAggCursor(false),
diff --git a/src/mongo/db/clientcursor.h b/src/mongo/db/clientcursor.h
index 5e3803225fc..9ffe1ac1318 100644
--- a/src/mongo/db/clientcursor.h
+++ b/src/mongo/db/clientcursor.h
@@ -71,9 +71,9 @@ namespace mongo {
bool isAggCursor = false);
/**
- * This ClientCursor is used to track sharding state.
+ * This ClientCursor is used to track sharding state for the given collection.
*/
- ClientCursor(CursorManager* cursorManager);
+ explicit ClientCursor(const Collection* collection);
//
// Basic accessors
diff --git a/src/mongo/db/range_preserver.h b/src/mongo/db/range_preserver.h
index 042987863c4..a8a5a5d75b0 100644
--- a/src/mongo/db/range_preserver.h
+++ b/src/mongo/db/range_preserver.h
@@ -52,7 +52,7 @@ namespace mongo {
// Empty collections don't have any data we need to preserve
if (collection) {
// Not a memory leak. Cached in a static structure by CC's ctor.
- ClientCursor* cc = new ClientCursor(collection->cursorManager());
+ ClientCursor* cc = new ClientCursor(collection);
// Pin keeps the CC from being deleted while it's in scope. We delete it ourselves.
_pin.reset(new ClientCursorPin(collection->cursorManager(), cc->cursorid()));