From cd5c79334fd796a7af7ac3e55e05637fa705cb56 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Sun, 13 Jun 2021 08:27:38 -0700 Subject: [PATCH] MPMCFIFO make limit optional --- src/pvxs/util.h | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/pvxs/util.h b/src/pvxs/util.h index 182a6b0..26eb5e2 100644 --- a/src/pvxs/util.h +++ b/src/pvxs/util.h @@ -183,7 +183,7 @@ std::ostream& target_information(std::ostream&); * to methods during destruction will result in undefined behavior. * * @code - * MPMCFIFO> Q(42); + * MPMCFIFO> Q; * ... * while(auto work = Q.pop()) { // Q.push(nullptr) to break loop * work(); @@ -194,7 +194,7 @@ std::ostream& target_information(std::ostream&); */ template class MPMCFIFO { - epicsMutex lock; + mutable epicsMutex lock; epicsEvent notifyW, notifyR; std::deque Q; const size_t nlimit; @@ -207,15 +207,23 @@ public: typedef T value_type; //! Construct a new queue - explicit MPMCFIFO(size_t limit) + //! @param limit If non-zero, then emplace()/push() will block while while + //! queue size is greater than or equal to this limit. + explicit MPMCFIFO(size_t limit=0u) :nlimit(limit) - { - if(!nlimit) - throw std::invalid_argument("MPMCFIFO limit must be >0"); - } + {} //! Destructor is not re-entrant ~MPMCFIFO() {} + //! Poll number of elements in the work queue at this moment. + size_t size() const { + Guard G(lock); + return Q.size(); + } + size_t max_size() const { + return nlimit ? nlimit : Q.max_size(); + } + /** Construct a new element into the queue. * * Will block while full. @@ -226,7 +234,7 @@ public: { Guard G(lock); // while full, wait for reader to consume an entry - while(Q.size()>=nlimit) { + while(nlimit && Q.size()>=nlimit) { nwriters++; { UnGuard U(G);