Search code examples
c++boostboost-threadinterruptions

boost::thread interrupt() throws an exception only the first time that an interruption point is executed?


boost::thread interrupt() throws an exception only the first time that an interruption point is executed? My case is the following.

I create a boost::thread which executes functionA. functionA calls functionB and when on functionB we call function threadInterrupt. functionB throws a boost::thread_interrupted exception and returns to functionA. My question is if a new boost::thread_interrupted exception will be throw in functionA when another interruption point is executed.

void MyClass::function(int arg1, int arg2) try {
    boost::thread* t = new boost::thread(boost::bind(&MyClass::functionA, this, var1, var2));
} catch (...) {
    cout << "function throw an exception" << endl;
}

void MyClass::functionA(int arg1, int arg2 ) try {
    //some code here
    try {
        int retVal = MyClass::functionB(var);
        boost::this_thread::interruption_point();
        //some code here
    } catch(boost::thread_interrupted&) {
        cout << "thread interrupted in functionA" << endl;
    }
} catch (...) {
    cout << "functionA throw an exception" << endl;
}

int MyClass::functionB(int arg1) try {
    //some code here
    try {
        boost::this_thread::interruption_point();
        //some code here
    } catch(boost::thread_interrupted&) {
        cout << "thread interrupted in functionB" << endl;
        return 0;
    }
    return 1;
} catch (...) {
    cout << "functionB throw an exception" << endl;
    return 1;
}

void MyClass::threadInterrupt() {
    if (thr!=NULL) {
        thr->interrupt();
        thr->join();
        delete thr;
        thr=NULL;
    }
}

Solution

  • Have you tried it? See it Live On Coliru

    #include <boost/thread.hpp>
    #include <iostream>
    
    using namespace boost;
    
    int main() {
        thread t([]{
                int i = 0;
                while (true) try {
                    if (i >= 10) return;
                    while (i < 10) {
                        this_thread::sleep_for(chrono::milliseconds(200));
                        std::cout << "processed " << i++ << "\n";
                    }
                }
                catch (...) { std::cout << "Interrupted at i = " << i << "\n"; }
        });
    
        this_thread::sleep_for(chrono::milliseconds(800));
        t.interrupt();
    
        t.join();
        std::cout << "Interrupt requested? : " << std::boolalpha << t.interruption_requested() << "\n";
    }
    

    Output:

    processed 0
    processed 1
    processed 2
    Interrupted at i = 3
    processed 3
    processed 4
    processed 5
    processed 6
    processed 7
    processed 8
    processed 9
    Interrupt requested? : false
    

    As you can see the interrupt request behaves like a sort of auto-reset flag.