std::vector< coroutine > queue_to_vec_cor( queue q, event::condition_variable* cv, event::mutex* mt, size_t min ) { if ( cv ) { assert( mt ); } std::vector< coroutine > cors; if ( q.type( ) == queue_type::serial ) { if ( cv ) { auto func = [ q = std::move( q ), cv, mt, min ]( ) mutable { for ( size_t i = 0; q.run_once( ); ++i ) { if ( i >= min ) { boost::lock_guard< event::mutex > lock( *mt ); cv->notify( ); } } }; cors.emplace_back( std::move( func ) ); } else { auto func = [q = std::move( q )]( ) mutable { q.run_until_empty( ); }; cors.emplace_back( std::move( func ) ); } } else { cors.reserve( q.work_queue.size( ) ); if ( cv ) { auto atomic = std::make_shared< std::atomic< size_t > >( 0 ); for ( auto& work : q.work_queue ) { auto func = [ work = std::move( work ), atomic, cv, mt, min ]( ) mutable { ( *work )( ); size_t atom_val = ++( *atomic ); if ( atom_val >= min ) { boost::lock_guard< event::mutex > lock( *mt ); cv->notify( ); } }; cors.emplace_back( std::move( func ) ); } } else { for ( auto& work : q.work_queue ) { cors.emplace_back( std::move( work ) ); } } } return cors; }
void queue::append_queue( queue q ) { boost::lock( queue_mut, q.queue_mut ); boost::lock_guard< boost::recursive_mutex > my_lock( queue_mut, boost::adopt_lock ); boost::lock_guard< boost::recursive_mutex > q_lock( q.queue_mut, boost::adopt_lock ); if ( typ == q.typ ) { std::move( q.work_queue.begin( ), q.work_queue.end( ), std::back_inserter( work_queue ) ); } else if ( typ == queue_type::parallel && q.typ == queue_type::serial ) { auto func = [q = std::move( q )]( ) mutable { q.run_until_empty( ); }; work_queue.emplace_back( new spec_functor< decltype( func ) >( std::move( func ) ) ); } else if ( typ == queue_type::serial && q.typ == queue_type::parallel ) { auto func = [q = std::move( q )]( ) mutable { event::mutex mt; event::condition_variable cv; boost::unique_lock< event::mutex > lock( mt ); auto size = q.work_queue.size( ); schedule_queue_first( std::move( q ), cv, mt, size ); cv.wait( lock ); }; work_queue.emplace_back( new spec_functor< decltype( func ) >( std::move( func ) ) ); } if ( cb_added ) { cb_added( *this ); } }