Search code examples
c++asynchronousc++17try-catch

Receive async exception directly


class ClassA
{
    void running()
    {
        int count = 0;

        m_worker_stop.store(true);
        while (m_worker_stop.load() == false)
        {
            count++;
            if (count == 10)
            {
                // Make exception
                std::vector v(100000000000);
            }            
        }
    }

    void start()
    {
        m_worker = std::async(std::launch::async, &ClassA::running, this);
    }

    void stop()
    {
        m_worker_stop.store(true);
        if (m_worker.valid())
            m_worker.get();    // catch exception in this point
    }

    std::future<void>   m_worker;
    std::atomic_bool    m_worker_stop = { false };
}

class Main    // this is single-ton Main class
{
    ...
    void running()
    {
        try {
            m_classA->start();

            // Wait for external signal(ex. SIGINT, SIGTERM, ..)
            while (true) { // signal check }

            m_classA->stop();
        }
        catch(std::exception& e) {
            // re-create throwed object
        }
        catch(...) {
            // re-create throwed object
        }
    }
}

int main()
{
    Manager::getInstance()::running();
    return 0;
}

Hello, everyone. The approximate structure of the program is as above.

In fact, I have not only classA but also many other objects such as B, C, and D. (start() and stop() function is simillar !)

An exception was raised using std::vector v(1000000..)

However, it became a catch when stop() was activated.

What I actually want is to delete the classA object and re-create it if an exception occurs.

So I need to catch directly when exception was occured.

In this case, is any idea to get exception without wait for signals?


Solution

  • Here is one way of achieving the effect you want:

    class Main    // this is single-ton Main class
    {
        ...
        void running()
        {
            for (size_t i = 0; i < max_tries; ++i)
            {
                try {
                    m_classA->start();
                        // Wait for external signal(ex. SIGINT, SIGTERM, ..)
                    while (true) { 
                       // signal check ...
                    }
                    m_classA->stop();
    
                    // path to happy ending :)
                    LOG("Main::running(): Operation successful.", 
                    return;
                }
                catch(std::exception& e) {
                    LOG("Main::running(): Exception caught: message:\"{}\"", e.what());
                }
                catch(...) {
                    LOG("Main::running(): Unspecified exception caught, aborting.");
                    return;  // Example of 'unrecoverable error'
                }
            
                // this part is only executed after an exception.
                m_classA->shut_down();   // if you need some special shut down after an error.
                m_classA.clear();        // this is redundant, but explicit (optional)
                m_classA = MakeMeAnA();  // call our favorite A construction method.
            }
    
            // path to total failure :(
            LOG("Main::running(): Exiting after {} failed attempts", max_tries);
        }
    
      private:
          static constexpr size_t max_tries = 3;
    };