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

add additional concurrency feature to definvoker

This commit is contained in:
Dwight 2010-12-21 12:23:41 -05:00
parent b670860174
commit 6250ccaa93

View File

@ -41,7 +41,7 @@ namespace mongo {
template< class V >
class DeferredInvoker {
public:
DeferredInvoker() {
DeferredInvoker() : _invokeMutex("deferredinvoker") {
_which = 0;
}
@ -55,9 +55,9 @@ namespace mongo {
/** call to process pending invocations.
concurrency: only one thread at a time may call invoke(). however other threads can call defer()
simultaneously.
concurrency: handled herein. multiple threads could call invoke(), but their efforts will be
serialized. the common case is that there is a single processor of invocations.
normally, you call this outside of any lock. but if you want to fully drain the queue,
call from within a read lock. a good way to drain :
{
@ -69,16 +69,19 @@ namespace mongo {
}
*/
void invoke() {
int full = _which;
int empty = _which ^ 1;
// flip
{
// flip defer to the other queue
readlock lk;
assert( _queues[empty].empty() ); // queue-ers only touch the active queue, not the other one
_which = empty;
mutex::scoped_lock lk2(_invokeMutex);
int cur = _which;
int other = _which ^ 1;
if( _queues[other].empty() )
_which = other;
}
{
mutex::scoped_lock lk(_invokeMutex);
_drain( _queues[_which^1] );
}
_drain( _queues[full] );
}
private:
@ -86,6 +89,9 @@ namespace mongo {
typedef vector<V> Queue;
Queue _queues[2];
// lock order when multiple locks: dbMutex, _invokeMutex
mongo::mutex _invokeMutex;
void _drain(Queue& queue) {
unsigned oldCap = queue.capacity();
for( Queue::iterator i = queue.begin(); i != queue.end(); i++ ) {