Client::Client(const string& name)
- : name(name)
+ : name(name), stop(false)
{
- c = new boost::condition_variable;
- t = NULL;
}
Client::~Client()
{
- // TODO
+ boost::unique_lock<boost::mutex> lock(mutex);
+ stop = true;
+ lock.unlock();
+
+ condition.notify_all();
+
+ thread.join(); // TODO this can block
}
void
Client::add_task(DBus::Connection& conn, DBus::Message& msg)
{
- if (!t)
- t = new boost::thread(boost::bind(&Client::worker, this));
+ if (thread.get_id() == boost::thread::id())
+ thread = boost::thread(boost::bind(&Client::worker, this));
- boost::unique_lock<boost::mutex> l(m);
+ boost::unique_lock<boost::mutex> lock(mutex);
tasks.push(Task(conn, msg));
- l.unlock();
+ lock.unlock();
- c->notify_one();
+ condition.notify_one();
}
-
void
Client::worker()
{
while (true)
{
- boost::unique_lock<boost::mutex> l(m);
+ boost::unique_lock<boost::mutex> lock(mutex);
+
+ while (tasks.empty() && !stop)
+ condition.wait(lock);
- while (tasks.empty())
- c->wait(l);
+ if (stop)
+ break;
- Task task = tasks.front();
- tasks.pop();
+ Task task = tasks.front();
+ tasks.pop();
- l.unlock();
+ lock.unlock();
dispatch(task.conn, task.msg);
}
DBus::Message msg;
};
- boost::condition_variable* c;
- boost::mutex m;
- boost::thread* t;
-
+ boost::condition_variable condition;
+ boost::mutex mutex;
+ boost::thread thread;
+ bool stop;
queue<Task> tasks;
void add_task(DBus::Connection& conn, DBus::Message& msg);