Changeset 3fc7948 for lib


Ignore:
Timestamp:
06/10/09 16:21:33 (12 years ago)
Author:
Shane Alcock <salcock@…>
Branches:
4.0.1-hotfixes, cachetimestamps, develop, dpdk-ndag, etsilive, getfragoff, help, libtrace4, master, ndag_format, pfring, rc-4.0.1, rc-4.0.2, rc-4.0.3, rc-4.0.4, ringdecrementfix, ringperformance, ringtimestampfixes
Children:
904c639
Parents:
c9754d0
Message:

Major rewrite of trace_event_device

  • Replaced FIONREAD ioctl with a select() to check whether data is available. The select() is probably slower but the ioctl was not working for newer versions of pcap under linux, due to the use of mmaped packet sockets which would not report the expected value for that ioctl.
  • Added checks for the return value of trace_read_packet so that we can catch any error or EOF events that occur rather than always returning a PACKET event

Thanks to Benjamin Black for bringing this to our attention.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/format_helper.c

    r91b72d3 r3fc7948  
    4141#include <string.h>
    4242#include <errno.h>
     43#include <time.h>
    4344#include "format_helper.h"
    4445
     
    6667                                        struct libtrace_packet_t *packet) {
    6768        struct libtrace_eventobj_t event = {0,0,0.0,0};
    68         int data;
     69
     70        fd_set rfds, rfds_param;
     71        int ret;
     72        int max_fd;
     73        struct timeval tv;
    6974
    7075        assert(trace != NULL);
    7176        assert(packet != NULL);
    7277       
     78        FD_ZERO(&rfds);
     79        FD_ZERO(&rfds_param);
     80
    7381        if (trace->format->get_fd) {
    7482                event.fd = trace->format->get_fd(trace);
     83                FD_SET(event.fd, &rfds);
     84                max_fd = event.fd;
    7585        } else {
    7686                event.fd = 0;
    77         }
    78         if (ioctl(event.fd,FIONREAD,&data)==-1) {
    79                 event.type = TRACE_EVENT_TERMINATE;
    80                 return event;
    81         }
     87                max_fd = -1;
     88        }
     89
     90        /* Use select() to perform a quick poll to check that there is data
     91         * available - we used to use FIONREAD here but that does not work
     92         * for mmapped pcap sockets. As recent pcap on linux (e.g. Ubuntu 9.04)
     93         * uses mmapped sockets by default, I've switched over to this
     94         * solution. */
     95
     96        do {
     97                tv.tv_sec = 0;
     98                tv.tv_usec = 0;
     99                rfds_param = rfds;
     100
     101                ret = select(max_fd + 1, &rfds_param, NULL, NULL, &tv);
     102                if (ret == -1 && errno != EINTR) {
     103                        event.type = TRACE_EVENT_TERMINATE;
     104                        return event;
     105                }
     106        } while (ret == -1);
     107
     108        if (FD_ISSET(event.fd, &rfds_param)) {
     109                event.size = trace_read_packet(trace,packet);
    82110               
    83         if (data>0) {
    84                 event.size = trace_read_packet(trace,packet);
    85                 event.type = TRACE_EVENT_PACKET;
     111                if (event.size < 1) {
     112                        /* Covers error and EOF events - terminate rather
     113                         * than report a packet as available */
     114                        if (trace_is_err(trace)) {
     115                                trace_perror(trace, "read packet");
     116                        }
     117                        event.type = TRACE_EVENT_TERMINATE;
     118                } else {
     119
     120                        event.type = TRACE_EVENT_PACKET;
     121                }
    86122                return event;
    87123        }
Note: See TracChangeset for help on using the changeset viewer.