Search code examples
c++multithreadingproducer-consumer

Passing data to function from different thread


I have long-running function in my C++ 11 application that is essentially sub_main. I need to inform this function about situation risen in different thread. Requirements:

  • The situation can be risen at any time
  • The application should handle the situation at most at single place (it can leave it unhandled as well)
  • It does not need to be ultra fast nor not-delayed in execution

As of now I considered two option:

  1. Pass object factory with factoree that contain internal queue of situations. The object is then polled at regular interval inside sub_main for new situations. Polled object is removed from queue. When application decide it will not handle the situation in particular place, it can move it back to global situations queue and next constructed factoree will get the situation (so it can be handled elsewhere in sub_main)
  2. Analogous situation, but instead of polling, use lambda function that updates local variable inside sub_main as needed. This version does not use continous polling, but is less readable

Both seems a bit complicated and I am wondering if I missed a more simple solution. The problem is the sub_main is being implemented outside of my library and I am providing end-user with my situations


Solution

  • I ended up using suggestion of @PhilBrubaker and Chain of Responsibility:

    void sub_main(std::shared_ptr<situation_register> situation_register)
    {
    
        std::unique_ptr<handler_instance> instance =
            situation_register->register(priority::main, [=](situation* s)
            {
                switch(s->get_type())
                {
                     case situation::screensaver:
                          s->get<situation_screensaver>()->prevent();
                          s->mark_as_handled();
                     break;
                }
            });
    
    
    }
    

    In this case, if function does NOT explicit says the situation was handled it will be passed to next registered handler (they are sorted based on priority). The handler_instance is lightweight object that will deregister handler in its destructor.