c++ - Async espera en el descriptor de archivo usando Boost Asio
boost-asio dbus (1)
Este es precisamente el problema null_buffers se designed null_buffers .
En ocasiones, un programa debe integrarse con una biblioteca de terceros que desee realizar las operaciones de E / S. Para facilitar esto, Boost.Asio incluye un tipo null_buffers que se puede usar con operaciones de lectura y escritura. Una operación null_buffers no regresa hasta que el objeto de E / S esté "listo" para realizar la operación.
Como ejemplo, para realizar una lectura sin bloqueo se puede usar algo como lo siguiente:
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));
}
}
También hay un excelente ejemplo incluido en la documentación.
Intento integrar D-Bus con mi aplicación boost::asio
.
D-Bus tiene una API que enumera un conjunto de descriptores de archivos Unix (principalmente sockets pero también pueden ser FIFO) para ser vistos. Cuando esos descriptores tienen algo que leer, debería informar a la API de D-Bus para que pueda leerlos y hacer su trabajo.
Actualmente estoy haciendo esto:
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));
}
Pero el controlador se llama de inmediato diciendo que tiene 0 bytes para leer. Me gustaría que se llame solo cuando haya algo que leer, pero boost :: asio NO PUEDE leerlo. Debería actuar solo como una select()
glorificada select()
. ¿Hay una manera simple de hacer eso?
PD: estoy usando extensivamente boost::asio
en mi software, esto es solo una pequeña parte, así que me gustaría no depender de glib
u otros mainloops.