Skip to content

non-terminal cancellation of parallel_group does not cancel remaining operations #458

@pgit

Description

@pgit

Synopsis: When signalling non-terminal cancellation to a parallel group, that signal is distributed to all operations correctly. But if only some of the operations react to the requested cancellation type, the remaining ones are not cancelled when the group completes.

Analysis: The parallel group handles the cancellation request here:

// If we are the first place to request cancellation, i.e. no operation has
// yet completed and requested cancellation, emit a signal for each
// operation in the group.
if (cancel_type != cancellation_type::none)
if (auto state = state_.lock())
if (state->cancellations_requested_++ == 0)
for (std::size_t i = 0; i < sizeof...(Ops); ++i)
state->cancellation_signals_[i].emit(cancel_type);

Later, when an operation completes as a result of the cancellation signal (e.g., with errc::operation_canceled), the following code gets executed:

// If we are the first operation to request cancellation, emit a signal
// for each operation in the group.
if (state_->cancellations_requested_++ == 0)
for (std::size_t i = 0; i < sizeof...(Ops); ++i)
if (i != I)
state_->cancellation_signals_[i].emit(cancel_type);

However, since state_->cancellations_requested_ is already incremented by L352, none of the other operations will be cancelled.

Expected Behavior: Interaction between cancellation seems tricky. But regardless of how individual operations handle cancellation, once an operation completes and the cancellation condition tells us to cancel, it must do so.

The cancellation type used for that should be terminal I suppose, but the cancellation condition callable can also return other types.

Experimentally removing L352 fixed the issue for me, but I don't know if that has other implications.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions