2012-06-29 2 views
3

При запуске strace по следующей программе:повышение :: ASIO против Libpcap: избежать вызова близко дважды

#include <boost/asio.hpp> 
#include <pcap.h> 

using namespace boost; 

int main(int argc, char* argv[]) 
{ 
    asio::io_service io; 
    asio::posix::stream_descriptor stream(io); 
    char errorBuffer[BUFSIZ]; 
    pcap_t* p = pcap_open_live("any", BUFSIZ, false, 0, errorBuffer); 
    stream.assign(pcap_get_selectable_fd(p)); 
    io.run(); 
    stream.close(); 
    pcap_close(p); 
    return 0; 
} 

я получаю:

close(6)        = 0 
setsockopt(6, SOL_PACKET, PACKET_RX_RING, {block_size=0, block_nr=0, frame_size=0, frame_nr=0}, 16) = -1 EBADF (Bad file descriptor) 
munmap(0xb733c000, 4145152)    = 0 
close(6)        = -1 EBADF (Bad file descriptor) 

Как вы можете видеть, close называется дважды то же fd (сначала stream.close(), затем pcap_close(p)). Хотя программа может и не иметь смысла, мне нужно позвонить как stream.close() (чтобы предотвратить io_service от звонка epoll_ctl на закрытом fd) и pcap_close(p) (для освобождения памяти, используемой pcap_t) - это происходит в многопоточной программе.

Любые идеи о том, как это сделать, не вызывая close на том же fd дважды?

ответ

5

A posix::stream_descriptor принимает на себя ответственность за дескриптор, он закрывает его при выходе из сферы действия. Чтобы разрешить двойное закрытие, дублируйте дескриптор перед назначением dup().