Here is the contract for cancelAsyncOperations:
The only implementation for cancelAsyncOperations is the one that SessionASIO provides, which calls into BatonASIO::cancelSession to remove the session from the underlying networking baton (here). This, however, does not ensure that outstanding operations for the session are canceled/interrupted. Consider the following:
- The networking baton (i.e., BatonASIO) notices activity on the file handle corresponding to one of the sessions, returns from polling, and starts processing the continuation for that session. This, for instance, could result in running this continuation for read operations.
- Another thread calls cancelAsyncOperations for this session, with the goal of canceling all async operations. This, however, doesn't have any impact since the session is already removed from the networking baton (see here).
- The continuation mentioned earlier may attempt to add the session to the baton again (e.g., from here for opportunisticRead). This is despite the original request to cancel all ongoing asynchronous operations for the session.
The expected outcome for this ticket is to write a test that mimics the behavior described above and reproduce this issue. Next, we should devise a cancelation mechanism that ensures SessionASIO keeps track of all of its asynchronous operations and awaits their cancelation before returning from cancelAsyncOperations. Note that cancelAsyncOperations does not have to await completion of asynchronous tasks.