micro-os-plus/micro-os-plus-iii

Skip waits if current thread is interrupted

Opened this issue · 3 comments

When a thread is interrupted during some wait() (for example event_flags::wait()) it returns early with EINTR.

If interrupt was already set when entering the wait() it does not return early but still returns EINTR.
I think this is inconsistent.

As the interruption has to be manually reset (and does not reset itself after it once triggered an early return), I think the expected behavior is that all wait()s return early as long as the flag is set.

To achieve this, we would have to check the interrupted flag before any wait() suspends the current thread and just return in case it is set.

I don't remember the details why the status reflecting the interruption requires a manual reset, but at first sight this was intended as a feature, not a bug.

As for the behaviour when entering wait() while the interrupted flag is still set, this looks like an oversight.

Do you suggest that, as long as the flag remains set, all synchronisation waits should return immediately and return EINTR?

Do you suggest that, as long as the flag remains set, all synchronisation waits should return immediately and return EINTR?

Yes, I think that's very useful, at least for my usecase.

thread workerThread
{
  [](void* arg) -> void*
  {
    while (true)
    {
       longRunningJobWithLotsOfWaits();
       if (this_thread::thread().interrupted()) break;
    }
  },
  nullptr
};

sysclock.sleep_for(1000);

// now I want to stop the thread immediately
workerThread.interrupt();
workerThread.join();

This would not be possible in a generic way if the interruption flag would reset itself.
Maybe this is actually what cancel() should do but it's not implemented yet.

Ok, we'll take a second look at POSIX thread interruption/cancellation and improve the behaviour.