c++can-bus

How to stop a C++ blocking read call


I'm reading CAN-BUS traffic under SocketCAN and C++ in GNU/Linux. I've found that the read call is blocking, and I'm struggling to figure out how to stop my program properly when I don't want to keep reading.

Of course, I could hit Ctrl+C if I've invoked the program from the terminal, but the point is to find a way to do it programmatically when some condition is met (e.g., record for 5 seconds, or when some event happens, like a flag is raised). A timeout could work, or something like a signal, but I don't know how to do it properly.

// Read (blocking)
nbytes = read(s, &frame, sizeof(struct can_frame));

Solution

  • Read is always blocking... you want to only read if data is waiting... so consider doing a poll on the socket first to see if data is available and if so THEN read it. You can loop over doing the poll until you no longer want to read anymore...

    bool pollIn(int fd)
    {
        bool returnValue{false};
        struct pollfd *pfd;
        pfd = calloc(1, sizeof(struct pollfd));
        pfd.fd = fd;
        pfd.events = POLLIN;
    
        int pollReturn{-1};
        pollReturn = poll(pfd, 1, 0);
    
        if (pollReturn > 0)
        {
            if (pfd.revents & POLLIN)
            {
                returnValue = true;
            }
        }
        free(pfd);
        return(returnValue);
    }
    

    The above should return if there is data waiting at the socket file descriptor.

    while(!exitCondition)
    {
      if(pollIn(fd))
      {
        nbytes = read(fd, &frame, sizeof(struct can_frame));
        // other stuff you need to do with your read
      }
    }