2011-01-13 44 views
23

Tôi đang cố gắng tích hợp D-Bus với ứng dụng boost::asio của tôi.Async chờ trên bộ mô tả tập tin bằng cách sử dụng Boost Asio

D-Bus có API liệt kê một bộ mô tả tệp Unix (chủ yếu là ổ cắm nhưng cũng có thể là FIFO) để được theo dõi. Khi những mô tả đó có nội dung cần đọc, tôi nên thông báo cho API D-Bus để nó có thể đọc và làm điều đó.

Hiện nay tôi đang làm điều này:

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

Nhưng xử lý được gọi ngay lập tức nói rằng nó có 0 byte để được đọc. Tôi muốn nó được gọi chỉ khi có một cái gì đó để được đọc, nhưng tăng :: asio KHÔNG THỂ đọc nó. Nó sẽ hoạt động giống như một số select() được tôn vinh. Có cách nào đơn giản để làm điều đó không?

PS: Tôi đang sử dụng rộng rãi boost::asio trong phần mềm của mình, đây chỉ là một phần nhỏ của nó, vì vậy tôi không muốn phụ thuộc vào glib hoặc các vòng lặp chính khác.

+0

API D-Bus bạn đang sử dụng là gì? Có phải API C cấp thấp không? –

Trả lời

26

Đây chính là vấn đề null_buffersdesigned cho.

Đôi khi một chương trình phải được tích hợp với thư viện của bên thứ ba muốn để thực hiện các hoạt động I/O. Để tạo điều kiện thuận lợi cho việc này, Boost.Asio bao gồm loại null_buffers có thể sử dụng với cả hoạt động đọc và ghi . Một hoạt động null_buffers không trở lại cho đến khi đối tượng I/O là "sẵn sàng" để thực hiện thao tác.

Như một ví dụ, để thực hiện một non-blocking đọc một cái gì đó giống như sau đây có thể được sử dụng:

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

Ngoài ra còn có một excellent example bao gồm trong tài liệu.

+0

Đây chỉ là những gì tôi đang tìm kiếm. Nó tích hợp hoàn hảo. Cảm ơn rất nhiều! –

+1

Hi Sam, bạn có thể giải thích thêm về ví dụ tuyệt vời được bao gồm trong tài liệu bạn đã đề cập không? Tôi muốn sử dụng 'third_party_lib.session' để đọc/AsyncRead/Write/AsyncWrite một cái gì đó, làm thế nào tôi có thể làm điều đó? Tôi vẫn chưa rõ. Ví dụ mô phỏng thứ ba_party_lib làm tôi bối rối. Cảm ơn. –

+0

@Peter hãy đặt câu hỏi mới, bao gồm phần nào của ví dụ bạn thấy khó hiểu. –

Các vấn đề liên quan