@ -71,8 +71,7 @@ private:
/** Mutex protects entire object */
/** Mutex protects entire object */
CWaitableCriticalSection cs ;
CWaitableCriticalSection cs ;
CConditionVariable cond ;
CConditionVariable cond ;
/* XXX in C++11 we can use std::unique_ptr here and avoid manual cleanup */
std : : deque < std : : unique_ptr < WorkItem > > queue ;
std : : deque < WorkItem * > queue ;
bool running ;
bool running ;
size_t maxDepth ;
size_t maxDepth ;
int numThreads ;
int numThreads ;
@ -101,15 +100,11 @@ public:
numThreads ( 0 )
numThreads ( 0 )
{
{
}
}
/*( Precondition: worker threads have all stopped
/** Precondition: worker threads have all stopped
* ( call WaitExit )
* ( call WaitExit )
*/
*/
~ WorkQueue ( )
~ WorkQueue ( )
{
{
while ( ! queue . empty ( ) ) {
delete queue . front ( ) ;
queue . pop_front ( ) ;
}
}
}
/** Enqueue a work item */
/** Enqueue a work item */
bool Enqueue ( WorkItem * item )
bool Enqueue ( WorkItem * item )
@ -118,7 +113,7 @@ public:
if ( queue . size ( ) > = maxDepth ) {
if ( queue . size ( ) > = maxDepth ) {
return false ;
return false ;
}
}
queue . push_back ( item ) ;
queue . emplace_back ( std : : unique_ptr < WorkItem > ( item ) ) ;
cond . notify_one ( ) ;
cond . notify_one ( ) ;
return true ;
return true ;
}
}
@ -127,18 +122,17 @@ public:
{
{
ThreadCounter count ( * this ) ;
ThreadCounter count ( * this ) ;
while ( running ) {
while ( running ) {
WorkItem * i = 0 ;
std : : unique_ptr < WorkItem > i ;
{
{
boost : : unique_lock < boost : : mutex > lock ( cs ) ;
boost : : unique_lock < boost : : mutex > lock ( cs ) ;
while ( running & & queue . empty ( ) )
while ( running & & queue . empty ( ) )
cond . wait ( lock ) ;
cond . wait ( lock ) ;
if ( ! running )
if ( ! running )
break ;
break ;
i = queue . front ( ) ;
i = std : : move ( queue . front ( ) ) ;
queue . pop_front ( ) ;
queue . pop_front ( ) ;
}
}
( * i ) ( ) ;
( * i ) ( ) ;
delete i ;
}
}
}
}
/** Interrupt and exit loops */
/** Interrupt and exit loops */