Получаю ли я состояние гонки с моим boost asio async_read? - PullRequest
0 голосов
/ 31 мая 2011
bool Connection::Receive(){
    std::vector<uint8_t> buf(1000);
    boost::asio::async_read(socket_,boost::asio::buffer(buf,1000),
            boost::bind(&Connection::handler, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));

    int rcvlen=buf.size();
    ByteBuffer b((std::shared_ptr<uint8_t>)buf.data(),rcvlen);
    if(rcvlen <= 0){
        buf.clear();
        return false;
    }
    OnReceived(b);
    buf.clear();
    return true;
}

Метод работает нормально, но только когда я делаю точку останова внутри него. Есть ли проблема со временем, когда он ожидает получения? Без точки останова ничего не получается.

1 Ответ

4 голосов
/ 31 мая 2011

Вы пытаетесь читать из приемного буфера сразу после запуска асинхронной операции, не дожидаясь ее завершения, поэтому она работает, когда вы устанавливаете точку останова.

Код после вашего async_read относится к Connection::handler, поскольку это обратный вызов, который вы сказали async_read для вызова после получения некоторых данных.

Обычно вам требуется функция start_read и handle_read_some:

void connection::start_read()
{
    socket_->async_read_some(boost::asio::buffer(read_buffer_),
        boost::bind(&connection::handle_read_some, shared_from_this(),
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred));
}

void connection::handle_read_some(const boost::system::error_code& error, size_t bytes_transferred)
{
    if (!error)
    {
        // Use the data here!

        start_read();
    }
}

Обратите внимание на shared_from_this, это важно, если вы хотите, чтобы время жизни вашего соединения автоматически определялось количеством ожидающих запросов ввода / вывода. Убедитесь, что ваш класс получен из boost::enable_shared_from_this<connection> и создан только с make_shared<connection>.

Для обеспечения этого ваш конструктор должен быть закрытым, и вы можете добавить объявление друга (версия C ++ 0x; если ваш компилятор не поддерживает это, вам придется самостоятельно ввести правильное количество аргументов):

template<typename T, typename... Arg> friend boost::shared_ptr<T> boost::make_shared(const Arg&...);

Также убедитесь, что ваш приемный буфер еще активен к тому времени, когда вызывается обратный вызов, предпочтительно с помощью переменной члена буфера статического размера вашего класса соединения.

...