template<typename T>
class msg_queue
{
public:
// preventing implicit generation of move constructor
~msg_queue() {}
void post(T&& msg)
{
std::lock_guard<std::mutex> lock(mtx);
queue.push_front(std::move(msg));
cond.notify_one();
}
bool wait_for(T& msg, std::chrono::milliseconds time)
{
std::unique_lock<std::mutex> lock(mtx);
bool b = cond.wait_for(lock, time, [this]{return !queue.empty(); });
if (b)
{
msg = std::move(queue.back());
queue.pop_back();
return true;
}
else
{
return false;
}
}
unsigned int size()
{
std::lock_guard<std::mutex> lock(mtx);
return queue.size();
}
void clear()
{
std::lock_guard<std::mutex> lock(mtx);
queue.clear();
}
private:
std::deque<T> queue;
std::condition_variable cond;
std::mutex mtx;
};
dGVtcGxhdGU8dHlwZW5hbWUgVD4KY2xhc3MgbXNnX3F1ZXVlCnsKcHVibGljOgogICAgLy8gcHJldmVudGluZyBpbXBsaWNpdCBnZW5lcmF0aW9uIG9mIG1vdmUgY29uc3RydWN0b3IKICAgIH5tc2dfcXVldWUoKSB7fQoKICAgIHZvaWQgcG9zdChUJiYgbXNnKQogICAgewogICAgICAgIHN0ZDo6bG9ja19ndWFyZDxzdGQ6Om11dGV4PiBsb2NrKG10eCk7CiAgICAgICAgcXVldWUucHVzaF9mcm9udChzdGQ6Om1vdmUobXNnKSk7CiAgICAgICAgY29uZC5ub3RpZnlfb25lKCk7CiAgICB9CgogICAgYm9vbCB3YWl0X2ZvcihUJiBtc2csIHN0ZDo6Y2hyb25vOjptaWxsaXNlY29uZHMgdGltZSkKICAgIHsKICAgICAgICBzdGQ6OnVuaXF1ZV9sb2NrPHN0ZDo6bXV0ZXg+IGxvY2sobXR4KTsKICAgICAgICBib29sIGIgPSBjb25kLndhaXRfZm9yKGxvY2ssIHRpbWUsIFt0aGlzXXtyZXR1cm4gIXF1ZXVlLmVtcHR5KCk7IH0pOwogICAgICAgIGlmIChiKQogICAgICAgIHsKICAgICAgICAgICAgbXNnID0gc3RkOjptb3ZlKHF1ZXVlLmJhY2soKSk7CiAgICAgICAgICAgIHF1ZXVlLnBvcF9iYWNrKCk7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQoKICAgIHVuc2lnbmVkIGludCBzaXplKCkKICAgIHsKICAgICAgICBzdGQ6OmxvY2tfZ3VhcmQ8c3RkOjptdXRleD4gbG9jayhtdHgpOwogICAgICAgIHJldHVybiBxdWV1ZS5zaXplKCk7CiAgICB9CgogICAgdm9pZCBjbGVhcigpCiAgICB7CiAgICAgICAgc3RkOjpsb2NrX2d1YXJkPHN0ZDo6bXV0ZXg+IGxvY2sobXR4KTsKICAgICAgICBxdWV1ZS5jbGVhcigpOwogICAgfQoKcHJpdmF0ZToKICAgIHN0ZDo6ZGVxdWU8VD4gcXVldWU7CiAgICBzdGQ6OmNvbmRpdGlvbl92YXJpYWJsZSBjb25kOwogICAgc3RkOjptdXRleCBtdHg7Cn07Cg==