0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00

SERVER-3208 refresh cached namespace pointers on update yield

This commit is contained in:
Aaron 2011-07-18 15:25:08 -07:00
parent 23c7fefdfe
commit 789bd622ae
4 changed files with 34 additions and 12 deletions

View File

@ -447,16 +447,29 @@ namespace mongo {
return rec;
}
bool ClientCursor::yieldSometimes( RecordNeeds need ) {
bool ClientCursor::yieldSometimes( RecordNeeds need, bool *yielded ) {
if ( yielded ) {
*yielded = false;
}
if ( ! _yieldSometimesTracker.ping() ) {
Record* rec = _recordForYield( need );
if ( rec )
if ( rec ) {
if ( yielded ) {
*yielded = true;
}
return yield( yieldSuggest() , rec );
}
return true;
}
int micros = yieldSuggest();
return ( micros > 0 ) ? yield( micros , _recordForYield( need ) ) : true;
if ( micros > 0 ) {
if ( yielded ) {
*yielded = true;
}
return yield( micros , _recordForYield( need ) );
}
return true;
}
void ClientCursor::staticYield( int micros , const StringData& ns , Record * rec ) {

View File

@ -186,9 +186,10 @@ namespace mongo {
/**
* @param needRecord whether or not the next record has to be read from disk for sure
* if this is true, will yield of next record isn't in memory
* @param yielded true if a yield occurred, and potentially if a yield did not occur
* @return same as yield()
*/
bool yieldSometimes( RecordNeeds need );
bool yieldSometimes( RecordNeeds need, bool *yielded = 0 );
static int yieldSuggest();
static void staticYield( int micros , const StringData& ns , Record * rec );

View File

@ -1060,11 +1060,10 @@ namespace mongo {
debug.updateobj = updateobj;
/* idea with these here it to make them loop invariant for multi updates, and thus be a bit faster for that case */
/* NOTE: when yield() is added herein, these must be refreshed after each call to yield! */
// idea with these here it to make them loop invariant for multi updates, and thus be a bit faster for that case
// The pointers may be left invalid on a failed yield recovery.
NamespaceDetails *d = nsdetails(ns); // can be null if an upsert...
NamespaceDetailsTransient *nsdt = &NamespaceDetailsTransient::get_w(ns);
/* end note */
auto_ptr<ModSet> mods;
bool isOperatorUpdate = updateobj.firstElementFieldName()[0] == '$';
@ -1105,6 +1104,9 @@ namespace mongo {
shared_ptr< MultiCursor::CursorOp > opPtr( new UpdateOp( mods.get() && mods->hasDynamicArray() ) );
shared_ptr< MultiCursor > c( new MultiCursor( ns, patternOrig, BSONObj(), opPtr, true ) );
d = nsdetails(ns);
nsdt = &NamespaceDetailsTransient::get_w(ns);
if( c->ok() ) {
set<DiskLoc> seenObjects;
MatchDetails details;
@ -1120,13 +1122,19 @@ namespace mongo {
cc.reset( new ClientCursor( QueryOption_NoCursorTimeout , cPtr , ns ) );
}
if ( ! cc->yieldSometimes( ClientCursor::WillNeed ) ) {
bool didYield;
if ( ! cc->yieldSometimes( ClientCursor::WillNeed, &didYield ) ) {
cc.release();
break;
}
if ( !c->ok() ) {
break;
}
if ( didYield ) {
d = nsdetails(ns);
nsdt = &NamespaceDetailsTransient::get_w(ns);
}
// *****************
// May have already matched in UpdateOp, but do again to get details set correctly
@ -1146,6 +1154,8 @@ namespace mongo {
if ( !c->ok() ) {
break;
}
d = nsdetails(ns);
nsdt = &NamespaceDetailsTransient::get_w(ns);
}
continue;
}
@ -1276,6 +1286,8 @@ namespace mongo {
if ( !c->ok() ) {
break;
}
d = nsdetails(ns);
nsdt = &NamespaceDetailsTransient::get_w(ns);
}
if (atomic)

View File

@ -1,7 +1,5 @@
// Test unsafe management of nsdt on update command yield SERVER-3208
if ( 0 ) { // SERVER-3208
prefixNS = db.jstests_updatef;
prefixNS.save( {} );
@ -24,5 +22,3 @@ for( i=0; i < 20; ++i ) {
}
s();
}