summaryrefslogtreecommitdiff
path: root/src/mongo/db/clientcursor.h
diff options
context:
space:
mode:
authorAaron <aaron@10gen.com>2012-04-29 19:50:04 -0700
committerAaron <aaron@10gen.com>2012-05-05 11:04:06 -0700
commit11491b034fd9d65356e548ba85659fef8e83d2f3 (patch)
tree034b09339d108dc7ec2d9c0903cf2f405bdcf0d3 /src/mongo/db/clientcursor.h
parent8434786dd10a0316d2a35329a57eeb6f115a8d90 (diff)
downloadmongo-11491b034fd9d65356e548ba85659fef8e83d2f3.tar.gz
SERVER-5101 Make ClientCursor::Pin exception safe and remove its manual release mechanism for failed yield recovery.
Diffstat (limited to 'src/mongo/db/clientcursor.h')
-rw-r--r--src/mongo/db/clientcursor.h43
1 files changed, 19 insertions, 24 deletions
diff --git a/src/mongo/db/clientcursor.h b/src/mongo/db/clientcursor.h
index 0b7d5c405e4..f6ee59bc637 100644
--- a/src/mongo/db/clientcursor.h
+++ b/src/mongo/db/clientcursor.h
@@ -87,38 +87,32 @@ namespace mongo {
had a bug, it could (or perhaps some sort of attack situation).
*/
class Pin : boost::noncopyable {
- ClientCursor *_c;
+ CursorId _cursorid;
public:
- ClientCursor * c() { return _c; }
+ ClientCursor *c() const { return ClientCursor::find( _cursorid ); }
void release() {
- if( _c ) {
- verify( _c->_pinValue >= 100 );
- _c->_pinValue -= 100;
- _c = 0;
+ ClientCursor *cursor = c();
+ _cursorid = INVALID_CURSOR_ID;
+ if ( cursor ) {
+ verify( cursor->_pinValue >= 100 );
+ cursor->_pinValue -= 100;
}
}
- /**
- * call this if during a yield, the cursor got deleted
- * if so, we don't want to use the point address
- */
- void deleted() {
- _c = 0;
- }
- ~Pin() { release(); }
- Pin(long long cursorid) {
- recursive_scoped_lock lock(ccmutex);
- _c = ClientCursor::find_inlock(cursorid, true);
- if( _c ) {
- if( _c->_pinValue >= 100 ) {
- _c = 0;
- uasserted(12051, "clientcursor already in use? driver problem?");
- }
- _c->_pinValue += 100;
+ ~Pin() { DESTRUCTOR_GUARD( release(); ) }
+ Pin( long long cursorid ) :
+ _cursorid( INVALID_CURSOR_ID ) {
+ recursive_scoped_lock lock( ccmutex );
+ ClientCursor *cursor = ClientCursor::find_inlock( cursorid, true );
+ if ( cursor ) {
+ uassert( 12051, "clientcursor already in use? driver problem?",
+ cursor->_pinValue < 100 );
+ cursor->_pinValue += 100;
+ _cursorid = cursorid;
}
}
};
- // This object assures safe and reliable cleanup of a ClientCursor.
+ /** Assures safe and reliable cleanup of a ClientCursor. */
class Holder : boost::noncopyable {
public:
Holder() : _c( 0 ), _id( INVALID_CURSOR_ID ) {}
@@ -143,6 +137,7 @@ namespace mongo {
}
operator bool() { return _c; }
ClientCursor * operator-> () { return _c; }
+ const ClientCursor * operator-> () const { return _c; }
/** Release ownership of the ClientCursor. */
void release() {
_c = 0;