Interrupting a boost::thread while interruptions are disabled

1.7k views Asked by At

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

1

There are 1 answers

1
Emile Cormier On BEST ANSWER

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.