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;
164 #ifdef CGU_USE_SCHED_YIELD
214 q.push(std::move(obj));
240 template<
class... Args>
243 q.emplace(std::forward<Args>(args)...);
310 obj = std::move(q.front());
377 if (
this != &other) {
378 lock2(mutex, other.mutex);
409 lock2(mutex, rhs.mutex);
412 std::queue<T, Container> temp{rhs.q};
443 q = std::move(rhs.q);
575 std::queue<T, Container> q;
587 #ifdef CGU_USE_SCHED_YIELD
638 q.push(std::move(obj));
665 template<
class... Args>
668 q.emplace(std::forward<Args>(args)...);
736 obj = std::move(q.front());
764 while (q.empty()) cond.
wait(mutex);
808 while (q.empty()) cond.
wait(mutex);
810 obj = std::move(q.front());
903 obj = std::move(q.front());
976 if (
this != &other) {
977 lock2(mutex, other.mutex);
982 if (!other.q.empty()) other.cond.
broadcast();
1021 lock2(mutex, rhs.mutex);
1024 std::queue<T, Container> temp{rhs.q};
1063 q = std::move(rhs.q);
1149 q((Thread::Mutex::Lock(rhs.mutex), rhs.q)) {}
1188 template <
class T,
class Container>
1217 template <
class T,
class Container>
1223 #if defined(CGU_USE_INHERITABLE_QUEUE) && !defined(DOXYGEN_PARSING)
1232 template <
class T,
class Allocator>
1233 class AsyncQueue<T, std::list<T, Allocator> > {
1235 typedef std::list<T, Allocator> Container;
1236 typedef typename Container::value_type
value_type;
1237 typedef typename Container::size_type
size_type;
1240 mutable Thread::Mutex mutex;
1246 class Q:
public std::queue<T, Container> {
1248 void splice_end(Container&& lst) {
1249 this->c.splice(this->c.end(), std::move(lst));
1253 void lock2(Thread::Mutex& m1, Thread::Mutex& m2) {
1256 if (!m2.trylock()) {
1261 #ifdef CGU_USE_SCHED_YIELD
1271 Container temp{obj};
1272 Thread::Mutex::Lock lock{mutex};
1274 q.splice_end(std::move(temp));
1278 Container temp{std::move(obj)};
1279 Thread::Mutex::Lock lock{mutex};
1281 q.splice_end(std::move(temp));
1284 template<
class... Args>
1285 void emplace(Args&&... args) {
1287 temp.emplace_back(std::forward<Args>(args)...);
1288 Thread::Mutex::Lock lock{mutex};
1290 q.splice_end(std::move(temp));
1294 Thread::Mutex::Lock lock{mutex};
1295 if (q.empty())
throw AsyncQueuePopError();
1301 Thread::Mutex::Lock lock{mutex};
1302 if (q.empty())
throw AsyncQueuePopError();
1303 obj = std::move(q.front());
1308 Thread::Mutex::Lock lock{mutex};
1309 if (q.empty())
throw AsyncQueuePopError();
1313 bool empty()
const {
1314 Thread::Mutex::Lock lock{mutex};
1319 Thread::Mutex::Lock lock{mutex};
1324 if (
this != &other) {
1325 lock2(mutex, other.mutex);
1334 lock2(mutex, rhs.mutex);
1344 Thread::Mutex::Lock lock{mutex};
1345 q = std::move(rhs.q);
1356 Thread::Mutex::Lock lock{mutex};
1369 template <
class T,
class Allocator>
1370 class AsyncQueueDispatch<T, std::list<T, Allocator> > {
1372 typedef std::list<T, Allocator> Container;
1373 typedef typename Container::value_type
value_type;
1374 typedef typename Container::size_type
size_type;
1377 mutable Thread::Mutex mutex;
1384 class Q:
public std::queue<T, Container> {
1386 void splice_end(Container&& lst) {
1387 this->c.splice(this->c.end(), std::move(lst));
1391 void lock2(Thread::Mutex& m1, Thread::Mutex& m2) {
1394 if (!m2.trylock()) {
1399 #ifdef CGU_USE_SCHED_YIELD
1409 Container temp{obj};
1410 Thread::Mutex::Lock lock{mutex};
1412 q.splice_end(std::move(temp));
1417 Container temp{std::move(obj)};
1418 Thread::Mutex::Lock lock{mutex};
1420 q.splice_end(std::move(temp));
1424 template<
class... Args>
1425 void emplace(Args&&... args) {
1427 temp.emplace_back(std::forward<Args>(args)...);
1428 Thread::Mutex::Lock lock{mutex};
1430 q.splice_end(std::move(temp));
1435 Thread::Mutex::Lock lock{mutex};
1436 if (q.empty())
throw AsyncQueuePopError();
1442 Thread::Mutex::Lock lock{mutex};
1443 if (q.empty())
throw AsyncQueuePopError();
1444 obj = std::move(q.front());
1449 Thread::Mutex::Lock lock{mutex};
1450 while (q.empty()) cond.
wait(mutex);
1451 Thread::CancelBlock b;
1457 Thread::Mutex::Lock lock{mutex};
1458 while (q.empty()) cond.
wait(mutex);
1459 Thread::CancelBlock b;
1460 obj = std::move(q.front());
1467 Thread::Mutex::Lock lock{mutex};
1471 Thread::CancelBlock b;
1480 Thread::Mutex::Lock lock{mutex};
1484 Thread::CancelBlock b;
1485 obj = std::move(q.front());
1491 Thread::Mutex::Lock lock{mutex};
1492 if (q.empty())
throw AsyncQueuePopError();
1496 bool empty()
const {
1497 Thread::Mutex::Lock lock{mutex};
1502 Thread::Mutex::Lock lock{mutex};
1507 if (
this != &other) {
1508 lock2(mutex, other.mutex);
1513 if (!other.q.empty()) other.cond.broadcast();
1519 lock2(mutex, rhs.mutex);
1530 Thread::Mutex::Lock lock{mutex};
1531 q = std::move(rhs.q);
1541 q((Thread::Mutex::Lock(rhs.mutex), rhs.q)) {}
1544 Thread::Mutex::Lock lock{mutex};
1550 #endif // CGU_USE_INHERITABLE_QUEUE