2021年3月5日星期五

Design pattern to ensure on_close() is called once after all async r/w's are finished?

This question is asked from the context of Boost ASIO (C++).

Say you are using a library to do some async i/o on a socket, where:

  • you are always waiting to receive data
  • you occasionally send some data

Since you are always waiting to receive data (e.g. you trigger another async_read() from your completion handler), at any given time, you will either have:

  1. an async read operation in progress
  2. an async read operation in progress and an async write operation in progress

Now say you wanted to call some other function, on_close(), when the connection closes. In Boost ASIO, a connection error or cancel() will cause any oustanding async reads/writes to give an error to your completion handler. But there is no guarantee whether you are in scenario 1. or 2., nor is there a guarantee that the write will error before the read or vice versa. So to implement this, I can only imagine adding two variables called is_reading and is_writing which are set to true by async_read() and async_write() respectively, and set to false by the completion handlers. Then, from either completion handler, when there is an error and I think the connection may be closing, I would check if there is still an async operation in the opposite direction, and call on_close() if not.

The code, more or less:

atomic_bool is_writing;  atomic_bool is_reading;    ...    void read_callback(error_code& error, size_t bytes_transferred)  {    is_reading = false;      if (error)    {      if (!is_writing) on_close();    }    else    {      process_data(bytes_transferred);          async_read(BUF_SIZE);  // this will set is_reading to true    }  }    void write_callback(error_code& error, size_t bytes_transferred)  {    is_writing = false;      if (error)    {      if (!is_reading) on_close();    }  }  

Assume that this is a single-threaded app, but the thread is handling multiple sockets so you can't just let the thread end.

Is there a better way to design this? To make sure on_close() is called after the last async operation finishes?

https://stackoverflow.com/questions/66486270/design-pattern-to-ensure-on-close-is-called-once-after-all-async-r-ws-are-fin March 05, 2021 at 11:17AM

没有评论:

发表评论