Details
-
Improvement
-
Resolution: Done
-
Major - P3
-
None
-
None
-
None
-
Fully Compatible
Description
long long ctmLast = 0; // so we don't have to do find() which is a little slow very often.
|
long long ClientCursor::allocCursorId_inlock() {
|
long long ctm = curTimeMillis64();
|
dassert( ctm );
|
long long x;
|
while ( 1 ) {
|
x = (((long long)rand()) << 32);
|
x = x ^ ctm;
|
if ( ctm != ctmLast || ClientCursor::find_inlock(x, false) == 0 )
|
break;
|
}
|
ctmLast = ctm;
|
return x;
|
}
|
1) Reserved values should be excluded. Currently I believe it is possible for this function to return 0 (used to indicate 'no cursor' in network messages). We should also verify that -1 (another sentinel value indicating 'invalid' internal to mongod) cannot be generated even if the system time is set incorrectly.
2) If a ClientCursor is created and destroyed in the same millisecond (could occur with a server side yield), its cursorid could potentially be reused quickly.
3) The id of a long lived cursor (~50 days) could potentially be reused while the cursor is still in use.
Many of the above are low probability events.