Search code examples
boostboost-threadinterrupted-exception

Interrupting a boost::thread while interruptions are disabled


While using boost::threads I have come across this interruption problem. When I do a boost::thread_interrupt from thread A on thread B, while B has interrupts disabled (boost::this_thread::disable_interrupts di), the interrupt seems to be lost. That is to say, that if I put a boost::thread::interruption_point() after interruption has been enabled, it does not throw the boost::thread_interrupted exception.

Is this the expected behavior or am I doing something wrong?

Thanks


Solution

  • Nothing in the documentation says that interruptions are re-triggered when thread B re-enables interruptions. I've tried a simple test program and can confirm the behaviour you describe.

    After re-enabling interruptions, you can check this_thread::interruption_requested() to see if there was an interruption requested while interruptions were disabled. If an interruption was indeed requested, you can throw a thread_interrupted exception yourself.

    Here's a working program that demonstrates this:

    #include <boost/thread.hpp>
    #include <iostream>
    
    using namespace std;
    using namespace boost;
    
    void threadB()
    {
        int ticks = 0;
        this_thread::disable_interruption* disabler = 0;
        try
        {
            while (ticks < 20)
            {
                if (ticks == 5)
                {
                    cout << "Disabling interruptions\n";
                    disabler = new this_thread::disable_interruption;
                }
                if (ticks == 15)
                {
                    cout << "Re-enabling interruptions\n";
                    delete disabler;
                    if (this_thread::interruption_requested())
                    {
                        cout << "Interrupt requested while disabled\n";
                        throw thread_interrupted();
                    }
                }
                cout << "Tick " << ticks << "\n";
                thread::sleep(get_system_time() + posix_time::milliseconds(100));
                ++ticks;
            }
        }
        catch (thread_interrupted)
        {
            cout << "Interrupted\n";
        }
    }
    
    int main()
    {
        thread b(&threadB);
        thread::sleep(get_system_time() + posix_time::milliseconds(1000));
        b.interrupt();
        cout << "main -> Interrupt!\n";
        b.join();
    }
    

    Hope this helps.