Подтвердить что ты не робот

Async ожидает файлового дескриптора, используя Boost Asio

Я пытаюсь интегрировать D-Bus с моим приложением boost::asio.

D-Bus имеет API, который перечисляет набор файловых дескрипторов Unix (главным образом сокетов, но также может быть FIFO) для просмотра. Когда эти дескрипторы должны что-то читать, я должен сообщить API D-Bus, чтобы он мог их читать и делать.

В настоящее время я делаю это:

using boost::asio::posix::stream_descriptor;
void read_handle(stream_descriptor* desc, const boost::system::error_code& ec,
                 std::size_t bytes_read)
{
    if (!ec) {
        stream_descriptor::bytes_readable command(true);
        descriptor->io_control(command);
        std::size_t bytes_readable = command.get();
        std::cout << "It thinks I should read" << bytes_readable
            << " bytes" << std::endl;
    } else {
        std::cout << "There was an error" << std::endl;
    }
}

void watch_descriptor(boost::asio::io_service& ios, int file_descriptor)
{
    // Create the asio representation of the descriptor
    stream_descriptor* desc = new stream_descriptor(ios);
    desc->assign(file_descriptor);

    // Try to read 0 bytes just to be informed that there is something to be read
    std::vector<char> buffer(0);
    desc->async_read_some(boost::asio::buffer(buffer, 0),
        boost::bind(read_handle, desc, _1, _2));
}

Но обработчик называется сразу, говоря, что он имеет 0 байтов для чтения. Я бы хотел, чтобы это вызывалось только тогда, когда есть что-то, что нужно прочитать, но boost:: asio НЕ МОЖЕТ читать. Он должен действовать так же, как прославленный select(). Есть ли простой способ сделать это?

PS: Я широко использую boost::asio в своем программном обеспечении, это лишь малая его часть, поэтому я бы не хотел зависеть от glib или других mainloops.

4b9b3361

Ответ 1

Именно проблема null_buffers была разработана для.

Иногда программа должна быть интегрирована с сторонней библиотекой, которая хочет для выполнения операций ввода-вывода. Чтобы облегчить это, Boost.Asio включает тип null_buffers, который может использоваться как для чтения, так и для записи операции. Операция null_buffers не возвращается, пока объект ввода-вывода не будет "готов" выполнить операцию.

В качестве примера, чтобы выполнить неблокирующие читают что-то вроде следующие могут быть использованы:

ip::tcp::socket socket(my_io_service);
...
ip::tcp::socket::non_blocking nb(true);
socket.io_control(nb);
...
socket.async_read_some(null_buffers(), read_handler);
...
void read_handler(boost::system::error_code ec)
{
  if (!ec)
  {
    std::vector<char> buf(socket.available());
    socket.read_some(buffer(buf));
  }
}

В документации также есть отличный пример.