0

これが私のコードです:

void client_connection::serve()
{
    asio::async_read(this->socket_, asio::buffer(&buffer_, buffer_.size()),

        // predicate/condition (do I wrap this?)
        std::bind(&client_connection::handle_read_predicate, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2),

        // handler
        this->strand_.wrap(std::bind(&client_connection::handle_read, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2)));
}

std::size_t client_connection::handle_read_predicate(const asio::error_code& error, std::size_t bytes_)
{
    // useless flawed function, for now

    // std::cout << "test: reached predicate, " << bytes_ << std::endl;

    return 0;
}

void client_connection::handle_read(const asio::error_code& error_, std::size_t bytes_)
{
    // useless flawed function, for now

    if (error_) return;

    this->serve();
}

私の質問は、 asio::io_service::strand を使用して述語/条件ハンドラーを同じ strand_ オブジェクトでラップするのが正しいかどうかです。ある場合はその理由、そうでない場合は説明してください。

4

1 に答える 1

3

ストランドに巻き付ける必要はありません。

文書化されたストランドに従って、free 関数などの構成された操作のasync_read場合、すべての中間ハンドラーはハンドラーのストランド内で呼び出されます。これの副作用は、すべての中間呼び出しがCompletionConditionストランド内からも呼び出されることです。

ただし、呼び出し元のコンテキスト内でclient_connection::serve()最初の非同期読み取りソケット操作が発生するため、非同期ループを開始するときは、必ずストランド内で最初の呼び出しをディスパッチしてください。CompletionConditionたとえば、次の図では、socket.async_read()client_connection::handle_read_predicate()、およびへのすべての呼び出しclient_connection::handle_read()がストランド内で発生します。

void client_connection::start()
{
  strand_.dispatch(std::bind(&client_connection::serve,
                             shared_from_this())) --------.
}                                                         |
    .-----------------------------------------------------'
    |  .--------------------------------------------------.
    V  V                                                  |
void client_connection::serve()                           |
{                                                         |
  async_read(socket_, buffer,                             |
    std::bind(&client_connection::handle_read_predicate,  |
              this),                                      |
    strand_.wrap(                                         |
      std::bind(&client_connection::handle_read,          |
                shared_from_this())); --.                 |
}                                       |                 |
    .-----------------------------------'                 |
    V                                                     |
void client_connection::handle_read(...)                  |
{                                                         |
  if (error) return;                                      |
  serve();  ----------------------------------------------'
}
于 2013-04-08T13:11:37.813 に答える