Skip to content

Perform cancellation in context destructor #40

Closed

Description

@kammce
No description provided.

Activity

  1. kammce commented on Jan 14, 2026

    @kammce
    MemberAuthor

    Changing this to a bug because it is one and its problematic. Currently, calling cancel in the destructor causes a segfault.

  2. kammce commented on Jan 16, 2026

    @kammce
    MemberAuthor

    One problem I ran into is "stack use after scope" when doing this. This is because derived class's stack memory may have been freed before the base context is executed. That means that the derived classes will need to call cancel() themselves in order to cancel their operations.

    I've been also thinking about when this would actually be important. For example, in what scenarios can a context be destroyed and it still have an operation on its stack.

    First, to even have an operation on the context stack, a future must exist somewhere that is bound to the context. If that future is destroyed, then it's operation and all sub operations are destroyed as well, leaving context empty with no need to call cancel itself.

    One could stack their operations, but once that's done, the memory is leaked and your stuck anyways. This would be erroneous behaviour.

    Another idea is if a future is moved from its scope to one that will extend its lifetime past the context, like moving the future to a global variable. If that happens then the lifetime of the future will outlive the context and the context will need to invoke cancel.

    Since futures can only be created with an existing context, they must have lifetimes shorter than the context it's associated with.

    So my thoughts are:

    1. Could a future be moved to dynamics memory extending its life to an unknown time?
    2. Could a future be moved to a global variable or to a member of a class?
    3. Could a future be placed into an optional<future<T>> that's above the creation of a context?

    One idea is to make futures immovable to prevent 1 and 2. But I don't think we can prevent a future from being constructed / assigned into some other container with greater lifetime than its context, such as vector or optional.

    So due to the 3rd thought above, I think we just need to do some checking to ensure we don't call destroy on things. This would require derived classes to call cancel(). And maybe we need a terminate clause if a context is destroyed but it's stack memory is empty.

  3. kammce commented on Jan 17, 2026

    @kammce
    MemberAuthor

    Resolved in #56

    I went with adding a type erased function to each promise to allow it cancel any typed future. This enables us to easily set each future to the cancelled state as we propagate from the bottom active coroutine up the chain.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions