#ifndef SYNC_H
#define SYNC_H
#include <basic/queue.h>
#include <boost/thread.hpp>
namespace af {
namespace sync {
template<typename T>
struct queue
{
// for convenient
typedef typename af::basic::queue<T> container;
struct monitor_t
{
monitor_t() : q_(0) {};
monitor_t(monitor_t& m) : q_(m.q_) {}
~monitor_t() {}
template<typename F>
void operator()(F& f) const
{
boost::lock_guard<boost::mutex> lock(q_->m_);
q_->c_.notify_one();
f(q_->q_);
}
private:
queue* q_;
// for setting reference
friend monitor_t queue::monitor();
};
queue() : q_() {}
bool empty() const
{
boost::lock_guard<boost::mutex> lock(m_);
return q_.empty();
}
size_t size() const
{
boost::lock_guard<boost::mutex> lock(m_);
return q_.size();
}
bool pop(T& msg, unsigned int ms)
{
boost::system_time const timeout
= boost::get_system_time()
+ boost::posix_time::milliseconds(ms);
boost::unique_lock<boost::mutex> lock(m_);
while( q_.empty())
{
if (!c_.timed_wait(lock, timeout))
return false;
}
q_.pop(msg);
return true;
}
// consumes msg and moves it into the queue
void push(T& msg)
{
boost::lock_guard<boost::mutex> lock(m_);
q_.push(msg);
c_.notify_one();
}
void clear()
{
boost::lock_guard<boost::mutex> lock(m_);
q_.clear();
}
monitor_t monitor()
{
monitor_t tmp;
tmp.q_ = this;
return tmp;
}
~queue()
{
clear();
}
private:
// do not copy
queue(queue const&);
queue& operator=(queue const&);
af::basic::queue<T> q_;
mutable boost::mutex m_;
boost::condition_variable c_;
};
}
}
I2lmbmRlZiBTWU5DX0gKI2RlZmluZSBTWU5DX0gKCiNpbmNsdWRlIDxiYXNpYy9xdWV1ZS5oPgojaW5jbHVkZSA8Ym9vc3QvdGhyZWFkLmhwcD4KCm5hbWVzcGFjZSBhZiB7Cm5hbWVzcGFjZSBzeW5jIHsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnN0cnVjdCBxdWV1ZQp7CiAgICAvLyBmb3IgY29udmVuaWVudAogICAgdHlwZWRlZiB0eXBlbmFtZSBhZjo6YmFzaWM6OnF1ZXVlPFQ+IGNvbnRhaW5lcjsKCiAgICBzdHJ1Y3QgbW9uaXRvcl90CiAgICB7CiAgICAgICAgbW9uaXRvcl90KCkgOiBxXygwKSB7fTsKICAgICAgICBtb25pdG9yX3QobW9uaXRvcl90JiBtKSA6IHFfKG0ucV8pIHt9CiAgICAgICAgfm1vbml0b3JfdCgpIHt9CgogICAgICAgIHRlbXBsYXRlPHR5cGVuYW1lIEY+CiAgICAgICAgdm9pZCBvcGVyYXRvcigpKEYmIGYpIGNvbnN0CiAgICAgICAgewogICAgICAgICAgICBib29zdDo6bG9ja19ndWFyZDxib29zdDo6bXV0ZXg+IGxvY2socV8tPm1fKTsKICAgICAgICAgICAgcV8tPmNfLm5vdGlmeV9vbmUoKTsKICAgICAgICAgICAgZihxXy0+cV8pOwogICAgICAgIH0KCiAgICBwcml2YXRlOgogICAgICAgIHF1ZXVlKiBxXzsKICAgICAgICAvLyBmb3Igc2V0dGluZyByZWZlcmVuY2UKICAgICAgICBmcmllbmQgbW9uaXRvcl90IHF1ZXVlOjptb25pdG9yKCk7CgogICAgfTsKCiAgICBxdWV1ZSgpIDogcV8oKSB7fQoKICAgIGJvb2wgZW1wdHkoKSBjb25zdAogICAgewogICAgICAgIGJvb3N0Ojpsb2NrX2d1YXJkPGJvb3N0OjptdXRleD4gbG9jayhtXyk7CiAgICAgICAgcmV0dXJuIHFfLmVtcHR5KCk7CiAgICB9CgogICAgc2l6ZV90IHNpemUoKSBjb25zdAogICAgewogICAgICAgIGJvb3N0Ojpsb2NrX2d1YXJkPGJvb3N0OjptdXRleD4gbG9jayhtXyk7CiAgICAgICAgcmV0dXJuIHFfLnNpemUoKTsKICAgIH0KCiAgICBib29sIHBvcChUJiBtc2csIHVuc2lnbmVkIGludCBtcykKICAgIHsKICAgICAgICBib29zdDo6c3lzdGVtX3RpbWUgY29uc3QgdGltZW91dAogICAgICAgICAgICA9IGJvb3N0OjpnZXRfc3lzdGVtX3RpbWUoKQogICAgICAgICAgICArIGJvb3N0Ojpwb3NpeF90aW1lOjptaWxsaXNlY29uZHMobXMpOwogICAgICAgIGJvb3N0Ojp1bmlxdWVfbG9jazxib29zdDo6bXV0ZXg+IGxvY2sobV8pOwogICAgICAgIHdoaWxlKCBxXy5lbXB0eSgpKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCFjXy50aW1lZF93YWl0KGxvY2ssIHRpbWVvdXQpKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgcV8ucG9wKG1zZyk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLy8gY29uc3VtZXMgbXNnIGFuZCBtb3ZlcyBpdCBpbnRvIHRoZSBxdWV1ZQogICAgdm9pZCBwdXNoKFQmIG1zZykKICAgIHsKICAgICAgICBib29zdDo6bG9ja19ndWFyZDxib29zdDo6bXV0ZXg+IGxvY2sobV8pOwogICAgICAgIHFfLnB1c2gobXNnKTsKICAgICAgICBjXy5ub3RpZnlfb25lKCk7CiAgICB9CgogICAgdm9pZCBjbGVhcigpCiAgICB7CiAgICAgICAgYm9vc3Q6OmxvY2tfZ3VhcmQ8Ym9vc3Q6Om11dGV4PiBsb2NrKG1fKTsKICAgICAgICBxXy5jbGVhcigpOwogICAgfQoKICAgIG1vbml0b3JfdCBtb25pdG9yKCkKICAgIHsKICAgICAgICBtb25pdG9yX3QgdG1wOwogICAgICAgIHRtcC5xXyA9IHRoaXM7CiAgICAgICAgcmV0dXJuIHRtcDsKICAgIH0KCiAgICB+cXVldWUoKQogICAgewogICAgICAgIGNsZWFyKCk7CiAgICB9Cgpwcml2YXRlOgoKICAgIC8vIGRvIG5vdCBjb3B5CiAgICBxdWV1ZShxdWV1ZSBjb25zdCYpOwogICAgcXVldWUmIG9wZXJhdG9yPShxdWV1ZSBjb25zdCYpOwoKICAgIGFmOjpiYXNpYzo6cXVldWU8VD4gcV87CiAgICBtdXRhYmxlIGJvb3N0OjptdXRleCBtXzsKICAgIGJvb3N0Ojpjb25kaXRpb25fdmFyaWFibGUgY187Cn07Cgp9Cn0K