From 0bf495f97002f65b73e7d2922e6f7fc5ea2a024d Mon Sep 17 00:00:00 2001 From: Ciro Nishiguchi Date: Tue, 17 Dec 2019 15:05:58 -0600 Subject: dpdk: Change client to wait on member variable Waiting on queue status seems to not always work, the queue state seems to not be updated immediately after pushing an item onto it when queried from a different thread. --- .../uhdlib/transport/dpdk_io_service_client.hpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'host/lib/include/uhdlib/transport') diff --git a/host/lib/include/uhdlib/transport/dpdk_io_service_client.hpp b/host/lib/include/uhdlib/transport/dpdk_io_service_client.hpp index 451cc1531..d994fe376 100644 --- a/host/lib/include/uhdlib/transport/dpdk_io_service_client.hpp +++ b/host/lib/include/uhdlib/transport/dpdk_io_service_client.hpp @@ -132,7 +132,7 @@ public: std::unique_lock lock(_waiter->mutex); wait_req_get(_waiter); _waiter->complete = false; - auto is_complete = [this] { return !rte_ring_empty(_buffer_queue); }; + auto is_complete = [this] { return _waiter->complete; }; if (timeout_ms < 0) { _waiter->cond.wait(lock, is_complete); } else { @@ -141,9 +141,11 @@ public: return frame_buff::uptr(); } } - if (rte_ring_dequeue(_buffer_queue, (void**)&buff_ptr)) { - return frame_buff::uptr(); - } + // Occasionally the conditional variable wait method returns but the + // first dequeue operation fails, even though we push onto it before + // setting complete to true. Retrying successfully dequeues a value + // in those cases. + while (rte_ring_dequeue(_buffer_queue, (void**)&buff_ptr)) {} } return frame_buff::uptr(buff_ptr); } @@ -240,7 +242,7 @@ public: std::unique_lock lock(_waiter->mutex); wait_req_get(_waiter); _waiter->complete = false; - auto is_complete = [this] { return !rte_ring_empty(_recv_queue); }; + auto is_complete = [this] { return _waiter->complete; }; if (timeout_ms < 0) { _waiter->cond.wait(lock, is_complete); } else { @@ -249,9 +251,11 @@ public: return frame_buff::uptr(); } } - if (rte_ring_dequeue(_recv_queue, (void**)&buff_ptr)) { - return frame_buff::uptr(); - } + // Occasionally the conditional variable wait method returns but the + // first dequeue operation fails, even though we push onto it before + // setting complete to true. Retrying successfully dequeues a value + // in those cases. + while (rte_ring_dequeue(_recv_queue, (void**)&buff_ptr)) {} } return frame_buff::uptr(buff_ptr); } -- cgit v1.2.3