71 #ifndef CGU_ASYNC_QUEUE_H
72 #define CGU_ASYNC_QUEUE_H
85 #ifdef CGU_USE_SCHED_YIELD
101 virtual const char*
what()
const throw() {
return "AsyncQueuePopError: popping from empty AsyncQueue object\n";}
145 template <
class T,
class Container = std::list<T> >
class AsyncQueue {
152 std::queue<T, Container> q;
165 #ifdef CGU_USE_SCHED_YIELD
215 q.push(std::move(obj));
241 template<
class... Args>
244 q.emplace(std::forward<Args>(args)...);
311 obj = std::move(q.front());
378 if (
this != &other) {
379 lock2(mutex, other.mutex);
410 lock2(mutex, rhs.mutex);
413 std::queue<T, Container> temp{rhs.q};
444 q = std::move(rhs.q);
576 std::queue<T, Container> q;
589 #ifdef CGU_USE_SCHED_YIELD
640 q.push(std::move(obj));
667 template<
class... Args>
670 q.emplace(std::forward<Args>(args)...);
738 obj = std::move(q.front());
766 while (q.empty()) cond.
wait(mutex);
810 while (q.empty()) cond.
wait(mutex);
812 obj = std::move(q.front());
905 obj = std::move(q.front());
978 if (
this != &other) {
979 lock2(mutex, other.mutex);
984 if (!other.q.empty()) other.cond.
broadcast();
1023 lock2(mutex, rhs.mutex);
1026 std::queue<T, Container> temp{rhs.q};
1065 q = std::move(rhs.q);
1151 q((Thread::Mutex::Lock(rhs.mutex), rhs.q)) {}
1190 template <
class T,
class Container>
1219 template <
class T,
class Container>
1225 #if defined(CGU_USE_INHERITABLE_QUEUE) && !defined(DOXYGEN_PARSING)
1234 template <
class T,
class Allocator>
1235 class AsyncQueue<T, std::list<T, Allocator> > {
1237 typedef std::list<T, Allocator> Container;
1238 typedef typename Container::value_type
value_type;
1239 typedef typename Container::size_type
size_type;
1242 mutable Thread::Mutex mutex;
1248 class Q:
public std::queue<T, Container> {
1250 void splice_end(Container&& lst) {
1251 this->c.splice(this->c.end(), std::move(lst));
1256 void lock2(Thread::Mutex& m1, Thread::Mutex& m2) {
1259 if (!m2.trylock()) {
1264 #ifdef CGU_USE_SCHED_YIELD
1274 Container temp{obj};
1275 Thread::Mutex::Lock lock{mutex};
1277 q.splice_end(std::move(temp));
1287 temp.push_back(std::move(obj));
1288 Thread::Mutex::Lock lock{mutex};
1290 q.splice_end(std::move(temp));
1293 template<
class... Args>
1294 void emplace(Args&&... args) {
1296 temp.emplace_back(std::forward<Args>(args)...);
1297 Thread::Mutex::Lock lock{mutex};
1299 q.splice_end(std::move(temp));
1303 Thread::Mutex::Lock lock{mutex};
1304 if (q.empty())
throw AsyncQueuePopError();
1310 Thread::Mutex::Lock lock{mutex};
1311 if (q.empty())
throw AsyncQueuePopError();
1312 obj = std::move(q.front());
1317 Thread::Mutex::Lock lock{mutex};
1318 if (q.empty())
throw AsyncQueuePopError();
1322 bool empty()
const {
1323 Thread::Mutex::Lock lock{mutex};
1328 Thread::Mutex::Lock lock{mutex};
1333 if (
this != &other) {
1334 lock2(mutex, other.mutex);
1343 lock2(mutex, rhs.mutex);
1353 Thread::Mutex::Lock lock{mutex};
1354 q = std::move(rhs.q);
1365 Thread::Mutex::Lock lock{mutex};
1378 template <
class T,
class Allocator>
1379 class AsyncQueueDispatch<T, std::list<T, Allocator> > {
1381 typedef std::list<T, Allocator> Container;
1382 typedef typename Container::value_type
value_type;
1383 typedef typename Container::size_type
size_type;
1386 mutable Thread::Mutex mutex;
1393 class Q:
public std::queue<T, Container> {
1395 void splice_end(Container&& lst) {
1396 this->c.splice(this->c.end(), std::move(lst));
1401 void lock2(Thread::Mutex& m1, Thread::Mutex& m2) {
1404 if (!m2.trylock()) {
1409 #ifdef CGU_USE_SCHED_YIELD
1419 Container temp{obj};
1420 Thread::Mutex::Lock lock{mutex};
1422 q.splice_end(std::move(temp));
1433 temp.push_back(std::move(obj));
1434 Thread::Mutex::Lock lock{mutex};
1436 q.splice_end(std::move(temp));
1440 template<
class... Args>
1441 void emplace(Args&&... args) {
1443 temp.emplace_back(std::forward<Args>(args)...);
1444 Thread::Mutex::Lock lock{mutex};
1446 q.splice_end(std::move(temp));
1451 Thread::Mutex::Lock lock{mutex};
1452 if (q.empty())
throw AsyncQueuePopError();
1458 Thread::Mutex::Lock lock{mutex};
1459 if (q.empty())
throw AsyncQueuePopError();
1460 obj = std::move(q.front());
1465 Thread::Mutex::Lock lock{mutex};
1466 while (q.empty()) cond.
wait(mutex);
1467 Thread::CancelBlock b;
1473 Thread::Mutex::Lock lock{mutex};
1474 while (q.empty()) cond.
wait(mutex);
1475 Thread::CancelBlock b;
1476 obj = std::move(q.front());
1483 Thread::Mutex::Lock lock{mutex};
1487 Thread::CancelBlock b;
1496 Thread::Mutex::Lock lock{mutex};
1500 Thread::CancelBlock b;
1501 obj = std::move(q.front());
1507 Thread::Mutex::Lock lock{mutex};
1508 if (q.empty())
throw AsyncQueuePopError();
1512 bool empty()
const {
1513 Thread::Mutex::Lock lock{mutex};
1518 Thread::Mutex::Lock lock{mutex};
1523 if (
this != &other) {
1524 lock2(mutex, other.mutex);
1529 if (!other.q.empty()) other.cond.broadcast();
1535 lock2(mutex, rhs.mutex);
1546 Thread::Mutex::Lock lock{mutex};
1547 q = std::move(rhs.q);
1557 q((Thread::Mutex::Lock(rhs.mutex), rhs.q)) {}
1560 Thread::Mutex::Lock lock{mutex};
1566 #endif // CGU_USE_INHERITABLE_QUEUE