предотвращение повышения сделать копию обработчик моего обратного вызова - PullRequest
1 голос
/ 12 августа 2010

Я написал небольшой tcp-клиент с использованием boost :: asio, обеспечивающий следующую функцию:

typedef boost::function<void(const bs::error_code& errCode, size_t bytesTransferred)> ReadHandler;

void CTcpClient::AsyncRead2(std::vector<char>& data, size_t length, ReadHandler readCompletedCallback)
{
    async_read(m_tcpData->socket, ba::buffer(data, length), readCompletedCallback);
}

Моя идея состоит в том, чтобы предложить пользователю асинхронных операций моего класса TcpClient, не беспокоясь об обработке потоков,io_services и т. д.

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

Заголовок CTestTcpClient

class CTestTcpClient : public ::testing::Test
{
public:
    CTestTcpClient(void);
    virtual ~CTestTcpClient(void);

    struct ReadCompletedHandler
    {
        ReadCompletedHandler() : m_isCompleted(false){};

        void operator()(const boost::system::error_code& errCode, size_t bytesTransferred)
        {
            m_isCompleted = true; // my breakpoint here, checking this pointer
        };

        bool isCompleted(void)
        {
            return m_isCompleted;
        }

    private:
        bool m_isCompleted;
    };

    ReadCompletedHandler m_readHandler;
};

CTestTcpClient source

TEST_F(CTestTcpClient, testAsynchronousRead_Success)
{
    CTcpClient client(testService);
    // Skipped code to setup echo server, connecting and sending of data
    // Receive echo
    vector<char> receiveBuffer(TESTDATA_SIZE);

    client.AsyncRead2(receiveBuffer, TESTDATA_SIZE, m_readHandler);

    while (!m_readHandler.isCompleted())
    {
        client.Wait(200);
    }
}

Теперь возникает проблема: цикл while никогда не завершится, поскольку флаг is_completed установлен в копии m_readHandler.Если я установлю точку останова в operator () моего обработчика, я смогу проверить и сравнить этот указатель.Кажется, что boost :: asio копирует мой обработчик, вызывает там оператор () и возвращает.Мой оригинальный обработчик никогда не трогается.

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

Спасибо за любую помощь

1 Ответ

1 голос
/ 12 августа 2010

Типичная идиома, которую я использовал для обработчиков завершения, - boost::bind функция-член, использующая boost::shared_from_this, чтобы гарантировать, что рассматриваемый объект не выходит за рамки. Это распространено почти во всех Boost.Asio примерах .

Если вы не хотите менять свой дизайн, вы можете попробовать boost::ref, например:

client.AsyncRead2(receiveBuffer, TESTDATA_SIZE, boost::ref(m_readHandler) );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...