Hi,


thanks for your patience. This is still unclear.


>  post() a method that calls close()


That's what I meant. I'll try to be more precise. QC below stands for the io_service's queue contents.

  1. io_service dequeues  and executes a completed read handler. This handler starts a new async read operation... QC: [] (empty). Pending: async_read.
  2. The program enqueues to io_service a lambda that calls close. QC: [ {close} ] Pending: async_read.
  3. In the mean-time (say, during the enqueue), the started async_read operation completed successfully in parallel because it didn't block at all. QC: [ {close} {ReadHandler} ] Pending: none.
  4. io_service dequeues {close}, nothing to cancel, the handle is closed. QC: [ {ReadHandler} ]
  5. io_service dequeues {ReadHandler}, which initiates a new read from the closed handle. QC: []

This assumes that asynchronous operations and notifications are, well, asynchronous. IOW, there is a time window (en-/dequeueing and execution of {close}) during which async_read can complete and end up non-cancellable, so {ReadHandler} is enqueued with success status.

What part of the puzzle am I missing?


From: Boost-users <boost-users-bounces@lists.boost.org> on behalf of Gavin Lambert via Boost-users <boost-users@lists.boost.org>
Sent: Wednesday, January 31, 2018 11:14 PM
To: boost-users@lists.boost.org
Cc: Gavin Lambert
Subject: Re: [Boost-users] asio: cancelling a named pipe client
 
On 1/02/2018 05:39, Stian Zeljko Vrba wrote:
> So is the following possible:
>
>  1. Another read operation is started, but that one completes
>     immediately because data is ready on the pipe. I.e., async_read_some
>     immediately posts the completion handler.
>  2. close() has nothing to cancel, but closes the socket.
>  3. The handler posted in 1 is executed, it goes to initiate another
>     read, and that read finds the pipe closed, returning
>     errc::invalid_handle.

No, because you don't call close() directly, you post() a method that
calls close(), which cannot execute before #3 unless either the
operation is still pending or you have already started a new operation
that is now pending.

> Even if async_read_some does *not* post the handler immediately but just
> initiates the I/O, this I/O can complete immediately and cannot be
> canceled on the OS-level. Thus attempted cancellation by close() will be
> a noop, the read handler will get an OK status and proceed to use the
> closed handle...

No, because the close hasn't actually happened yet, it's still sitting
in the queue.

The queue itself is OS-managed, so the moment the operation completes it
will push the completion handler to the queue.  It doesn't require
intervention from ASIO code.

_______________________________________________
Boost-users mailing list
Boost-users@lists.boost.org
https://lists.boost.org/mailman/listinfo.cgi/boost-users