2011-01-13 18 views
23

Próbuję zintegrować D-Bus z moją aplikacją boost::asio.Asynch czekać na deskryptor pliku za pomocą Boost Asio

D-Bus ma interfejs API, który wylicza zestaw deskryptorów plików Unix (głównie gniazda, ale może również być FIFO) do obejrzenia. Gdy te deskryptory mają coś do przeczytania, powinienem poinformować D-Bus API, aby mógł je przeczytać i zrobić to.

Obecnie robię tak:

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)); 
} 

Ale obsługi nazywany jest od razu powiedzieć, że ma 0 bajtów do odczytu. Chciałbym, żeby to było wywoływane tylko wtedy, gdy jest coś do odczytania, ale boost :: asio CAN NOT przeczytać. Powinien działać tak, jak uwielbiony select(). Czy istnieje prosty sposób na zrobienie tego?

PS: W moim oprogramowaniu intensywnie używam boost::asio, jest to tylko niewielka jego część, więc nie chciałbym polegać na glib lub innych urządzeniach głównych.

+0

Co to jest interfejs D-Bus API, którego używasz? Czy jest to C API niskiego poziomu? –

Odpowiedz

26

To jest właśnie problem null_buffers został designed dla.

Czasami program musi być zintegrowany z biblioteką trzeciej, która chce wykonywać operacje We/Wy sobie. Aby to ułatwić, funkcja Boost.Asio zawiera typ null_buffers, który może być używany z operacjami odczytu i zapisu . Operacja null_buffers nie powraca, dopóki obiekt I/O nie jest "gotowy" do wykonania operacji.

Jako przykład, aby przeprowadzić nieblokujące czytać coś jak mogą być stosowane następujące:

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)); 
    } 
} 

Jest też excellent example zawarte w dokumentacji.

+0

Tego właśnie szukałem. Zintegrował się idealnie. Wielkie dzięki! –

+1

Witam Sam, czy możesz wyjaśnić więcej o doskonałym przykładzie zawartym w dokumentacji, o której wspomniałeś? Chcę użyć 'third_party_lib.session' do odczytu/AsyncRead/Write/AsyncWrite coś, jak mogę to zrobić? Wciąż nie jest to takie jasne. Przykład symulujący third_party_lib faktycznie mnie zdezorientował. Dzięki. –

+0

@Peter proszę zadać nowe pytanie, podać, która część przykładu wydaje się być myląca. –

Powiązane problemy