summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron <aaron@10gen.com>2011-03-21 17:44:29 -0700
committerAaron <aaron@10gen.com>2011-03-22 22:12:54 -0700
commit0d5979c50b07075f608e8341f3629e786badc5ca (patch)
tree6e8342366b6a162fb98250394da6f8de6cd81090
parent7e593365957dac139531b0ede79d9f0df217f584 (diff)
downloadmongo-0d5979c50b07075f608e8341f3629e786badc5ca.tar.gz
SERVER-2809 don't read cursor's nscanned if failed yield invalidated the cursor
-rw-r--r--db/dbhelpers.cpp1
-rw-r--r--db/query.cpp12
-rw-r--r--db/update.cpp3
-rw-r--r--jstests/slowNightly/explain2.js18
4 files changed, 26 insertions, 8 deletions
diff --git a/db/dbhelpers.cpp b/db/dbhelpers.cpp
index 75db4308c25..3079aade5e8 100644
--- a/db/dbhelpers.cpp
+++ b/db/dbhelpers.cpp
@@ -85,6 +85,7 @@ namespace mongo {
}
}
virtual long long nscanned() {
+ // We don't support yielding, so will always have c_.
assert( c_.get() );
return c_->nscanned();
}
diff --git a/db/query.cpp b/db/query.cpp
index 50e2fc385fa..eaf508bf508 100644
--- a/db/query.cpp
+++ b/db/query.cpp
@@ -76,8 +76,7 @@ namespace mongo {
}
}
virtual long long nscanned() {
- assert( c_.get() );
- return c_->nscanned();
+ return c_.get() ? c_->nscanned() : _nscanned;
}
virtual void next() {
if ( !c_->ok() ) {
@@ -416,6 +415,7 @@ namespace mongo {
_ns(ns), _capped(false), _count(), _myCount(),
_skip( spec["skip"].numberLong() ),
_limit( spec["limit"].numberLong() ),
+ _nscanned(),
_bc() {
}
@@ -430,8 +430,7 @@ namespace mongo {
}
virtual long long nscanned() {
- assert( _c.get() );
- return _c->nscanned();
+ return _c.get() ? _c->nscanned() : _nscanned;
}
virtual bool prepareToYield() {
@@ -465,6 +464,7 @@ namespace mongo {
return;
}
+ _nscanned = _c->nscanned();
if ( _bc ) {
if ( _firstMatch.isEmpty() ) {
_firstMatch = _bc->currKeyNode().key.copy();
@@ -527,6 +527,7 @@ namespace mongo {
long long _myCount;
long long _skip;
long long _limit;
+ long long _nscanned;
shared_ptr<Cursor> _c;
BSONObj _query;
BtreeCursor * _bc;
@@ -740,8 +741,7 @@ namespace mongo {
if ( _findingStartCursor.get() ) {
return 0; // should only be one query plan, so value doesn't really matter.
}
- assert( _c.get() );
- return _c->nscanned();
+ return _c.get() ? _c->nscanned() : _nscanned;
}
virtual void next() {
diff --git a/db/update.cpp b/db/update.cpp
index 7de9bb1a573..a7b0a2a7813 100644
--- a/db/update.cpp
+++ b/db/update.cpp
@@ -913,8 +913,7 @@ namespace mongo {
}
}
virtual long long nscanned() {
- assert( _c.get() );
- return _c->nscanned();
+ return _c.get() ? _c->nscanned() : _nscanned;
}
virtual void next() {
if ( ! _c->ok() ) {
diff --git a/jstests/slowNightly/explain2.js b/jstests/slowNightly/explain2.js
new file mode 100644
index 00000000000..032f0fa8de8
--- /dev/null
+++ b/jstests/slowNightly/explain2.js
@@ -0,0 +1,18 @@
+// Test for race condition SERVER-2807. One cursor is dropped and another is not.
+
+collName = 'jstests_slowNightly_explain2';
+
+t = db[ collName ];
+t.drop();
+
+db.createCollection( collName, {capped:true,size:100000} );
+t = db[ collName ];
+t.ensureIndex( {x:1} );
+
+a = startParallelShell( 'for( i = 0; i < 50000; ++i ) { db.' + collName + '.insert( {x:i,y:1} ); }' );
+
+for( i = 0; i < 800; ++i ) {
+ t.find( {x:{$gt:-1},y:1} ).sort({x:-1}).explain();
+}
+
+a(); \ No newline at end of file