Skip to content

Instantly share code, notes, and snippets.

@Indy9000
Last active November 13, 2017 16:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Indy9000/1912a3cef1b223771e39091f293fed97 to your computer and use it in GitHub Desktop.
Save Indy9000/1912a3cef1b223771e39091f293fed97 to your computer and use it in GitHub Desktop.
Active Object Pattern
#include <functional>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <iostream>
class Active {
public:
using Message = std::function<void()>;
Active():keep_running(true){
thd = std::thread([this]{ // mainline: dispatch loop {}
while(keep_running){
Message m;
bool is_valid{false};
{//pop message
std::lock_guard<std::mutex> lg(qmut);
if(!mq.empty()){
m = mq.front();
mq.pop();
is_valid =true;
}
}
//execute
if(is_valid){
m();
}
{//wait for more
std::unique_lock<std::mutex> lk(qmut);
cv.wait(lk,[&]{return !mq.empty();});
}
}
});
}
~Active() { // shut down
keep_running = false;
Send( [=]{ ; } );// send sentinel and
if(thd.joinable()){
thd.join();// wait for msgs to drain
}
}
Active(const Active&)=delete;
Active& operator=(const Active& other)=delete;
void Send(const Message m) { // enqueue a message
{
std::lock_guard<std::mutex> lg(qmut);
mq.push(std::move(m));
}
cv.notify_one();
}
private:
bool keep_running;
std::queue<Message> mq;
std::mutex qmut;
std::thread thd;
std::condition_variable cv;
};
int main(){
Active a;
a.Send([](){
std::cout << "Hello from Active object" << std::endl;
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment