Skip to content

Commit

Permalink
Merge branch 'master' of github.com:mongodb/mongo
Browse files Browse the repository at this point in the history
  • Loading branch information
astaple committed Jul 8, 2010
2 parents a84e4a1 + 0adc465 commit cca87c3
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 116 deletions.
93 changes: 55 additions & 38 deletions db/clientcursor.cpp
Expand Up @@ -199,39 +199,57 @@ namespace mongo {
c->noteLocation();
}

bool ClientCursor::yieldSometimes(){
if ( ! _yieldSometimesTracker.ping() )
return true;

int ClientCursor::yieldSuggest() {
int writers = 0;
int readers = 0;

int micros = Client::recommendedYieldMicros( &writers , &readers );
if ( micros == 0 )
return true;

if ( writers == 0 && dbMutex.getState() <= 0 ){
if ( micros > 0 && writers == 0 && dbMutex.getState() <= 0 ){
// we have a read lock, and only reads are coming on, so why bother unlocking
return true;
micros = 0;
}

return yield( micros );
return micros;
}

bool ClientCursor::yieldSometimes(){
if ( ! _yieldSometimesTracker.ping() )
return true;

bool ClientCursor::yield( int micros ) {
// need to store on the stack in case this gets deleted
CursorId id = cursorid;
int micros = yieldSuggest();
return ( micros > 0 ) ? yield( micros ) : true;
}

bool doingDeletes = _doingDeletes;
void ClientCursor::staticYield( int micros ) {
{
dbtempreleasecond unlock;
if ( unlock.unlocked() ){
if ( micros == -1 )
micros = Client::recommendedYieldMicros();
if ( micros > 0 )
sleepmicros( micros );
}
else {
log( LL_WARNING ) << "ClientCursor::yield can't unlock b/c of recursive lock" << endl;
}
}
}

void ClientCursor::prepareToYield( YieldData &data ) {
// need to store in case 'this' gets deleted
data._id = cursorid;

data._doingDeletes = _doingDeletes;
_doingDeletes = false;

updateLocation();

{
/* a quick test that our temprelease is safe.
todo: make a YieldingCursor class
and then make the following code part of a unit test.
*/
todo: make a YieldingCursor class
and then make the following code part of a unit test.
*/
const int test = 0;
static bool inEmpty = false;
if( test && !inEmpty ) {
Expand All @@ -247,28 +265,27 @@ namespace mongo {
dropDatabase(ns.c_str());
}
}
}

{
dbtempreleasecond unlock;
if ( unlock.unlocked() ){
if ( micros == -1 )
micros = Client::recommendedYieldMicros();
if ( micros > 0 )
sleepmicros( micros );
}
else {
log( LL_WARNING ) << "ClientCursor::yield can't unlock b/c of recursive lock" << endl;
}
}

if ( ClientCursor::find( id , false ) == 0 ){
// i was deleted
}
}

bool ClientCursor::recoverFromYield( const YieldData &data ) {
ClientCursor *cc = ClientCursor::find( data._id , false );
if ( cc == 0 ){
// id was deleted
return false;
}

cc->_doingDeletes = data._doingDeletes;
return true;
}

bool ClientCursor::yield( int micros ) {
YieldData data;
prepareToYield( data );

staticYield( micros );

_doingDeletes = doingDeletes;
return true;
return ClientCursor::recoverFromYield( data );
}

int ctmLast = 0; // so we don't have to do find() which is a little slow very often.
Expand Down
7 changes: 7 additions & 0 deletions db/clientcursor.h
Expand Up @@ -156,6 +156,13 @@ namespace mongo {
* @return same as yield()
*/
bool yieldSometimes();

static int yieldSuggest();
static void staticYield( int micros );

struct YieldData { CursorId _id; bool _doingDeletes; };
void prepareToYield( YieldData &data );
static bool recoverFromYield( const YieldData &data );

struct YieldLock : boost::noncopyable {
explicit YieldLock( ptr<ClientCursor> cc )
Expand Down
23 changes: 14 additions & 9 deletions db/oplog.h
Expand Up @@ -95,7 +95,6 @@ namespace mongo {
return;
}
}
maybeRelease();
return;
}
case FindExtent: {
Expand All @@ -112,7 +111,6 @@ namespace mongo {
// There might be a more efficient implementation than creating new cursor & client cursor each time,
// not worrying about that for now
createClientCursor( prev );
maybeRelease();
return;
}
case InExtent: {
Expand All @@ -123,14 +121,25 @@ namespace mongo {
return;
}
_findingStartCursor->c->advance();
maybeRelease();
return;
}
default: {
massert( 12600, "invalid _findingStartMode", false );
}
}
}
}
void prepareToYield() {
if ( _findingStartCursor ) {
_findingStartCursor->prepareToYield( _yieldData );
}
}
void recoverFromYield() {
if ( _findingStartCursor ) {
if ( !ClientCursor::recoverFromYield( _yieldData ) ) {
_findingStartCursor = 0;
}
}
}
private:
enum FindingStartMode { Initial, FindExtent, InExtent };
const QueryPlan &_qp;
Expand All @@ -140,6 +149,7 @@ namespace mongo {
Timer _findingStartTimer;
ClientCursor * _findingStartCursor;
shared_ptr<Cursor> _c;
ClientCursor::YieldData _yieldData;
DiskLoc startLoc( const DiskLoc &rec ) {
Extent *e = rec.rec()->myExtent( rec );
if ( !_qp.nsd()->capLooped() || ( e->myLoc != _qp.nsd()->capExtent ) )
Expand Down Expand Up @@ -178,11 +188,6 @@ namespace mongo {
_findingStartCursor = 0;
}
}
void maybeRelease() {
if ( ! _findingStartCursor->yieldSometimes() ){
_findingStartCursor = 0;
}
}
void init() {
// Use a ClientCursor here so we can release db mutex while scanning
// oplog (can take quite a while with large oplogs).
Expand Down

0 comments on commit cca87c3

Please sign in to comment.