diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/catalog/cursor_manager.cpp | 27 | ||||
-rw-r--r-- | src/mongo/db/catalog/cursor_manager.h | 2 | ||||
-rw-r--r-- | src/mongo/db/clientcursor.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/clientcursor.h | 4 | ||||
-rw-r--r-- | src/mongo/db/range_preserver.h | 2 |
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())); |