|
|
@ -15,6 +15,7 @@ namespace utility |
|
|
|
typedef std::recursive_mutex Mutex; |
|
|
|
typedef std::unique_lock<Mutex> Lock; |
|
|
|
|
|
|
|
int _waiting = 0; |
|
|
|
Mutex _mtx; |
|
|
|
std::condition_variable_any _cv; |
|
|
|
std::deque<T> _q; |
|
|
@ -83,11 +84,14 @@ namespace utility |
|
|
|
bool try_pop_back(T& out, std::chrono::steady_clock::time_point end_time) |
|
|
|
{ |
|
|
|
Lock L(_mtx); |
|
|
|
++_waiting; |
|
|
|
if(! _cv.wait_until(L, end_time, [this]{ return !_q.empty(); } ) ) |
|
|
|
{ |
|
|
|
--_waiting; |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
--_waiting; |
|
|
|
out = std::move(_q.back()); |
|
|
|
_q.pop_back(); |
|
|
|
return true; |
|
|
@ -98,11 +102,14 @@ namespace utility |
|
|
|
bool try_pop_front(T& out, std::chrono::steady_clock::time_point end_time) |
|
|
|
{ |
|
|
|
Lock L(_mtx); |
|
|
|
++_waiting; |
|
|
|
if(! _cv.wait_until(L, end_time, [this]{ return !_q.empty(); } ) ) |
|
|
|
{ |
|
|
|
--_waiting; |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
--_waiting; |
|
|
|
out = std::move(_q.front()); |
|
|
|
_q.pop_front(); |
|
|
|
return true; |
|
|
@ -113,11 +120,14 @@ namespace utility |
|
|
|
bool try_pop_front(T& out, std::chrono::seconds duration) |
|
|
|
{ |
|
|
|
Lock L(_mtx); |
|
|
|
++_waiting; |
|
|
|
if(! _cv.wait_for(L, duration, [this]{ return !_q.empty(); } ) ) |
|
|
|
{ |
|
|
|
--_waiting; |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
--_waiting; |
|
|
|
out = std::move(_q.front()); |
|
|
|
_q.pop_front(); |
|
|
|
return true; |
|
|
@ -162,6 +172,13 @@ namespace utility |
|
|
|
Lock lg(_mtx); |
|
|
|
return _q.empty(); |
|
|
|
} |
|
|
|
|
|
|
|
// returns the number of threads that are waiting in pop_...() or try_pop_...()
|
|
|
|
int waiting() |
|
|
|
{ |
|
|
|
Lock L(_mtx); |
|
|
|
return _waiting; |
|
|
|
} |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
} // end of namespace utility
|
|
|
|