How to handle ENOBUFS

In some circumstances I'm getting a socket error ENOBUFS, which indicates that some buffer (probably related to sending or receiving packets) is full.

Is it safe to do the following when sending, or do I risk an infinite loop here? If this is unsafe, what else is one supposed to do? Try with increasing sleep delay for a finite number of times and disconnect afterwards?

ssize_t bytes = send(socket,string,length,0);
while(errno == ENOBUFS)
{
    tx_thread_sleep(10);
    ssize_t bytes = send(socket,string,length,0);
}

Also, when receiving, does this error mean that packets have been dropped because they haven't been processed fast enough? If yes, is it safe to ignore this error conedition when calling recv()?

  • Hi ChrisS,

    When it comes to send(), ENOBUFS is set when there is not enough packets available in the packet pool. It depends how your application makes use of the packet pool, but anyway I suggest making at most N attempts to send a packet and then failing.

    I don't think recv() will ever cause ENOBUFS error, I would expect EAGAIN if there is no packet.

    Regards,
    adboc
  • In reply to adboc:

    Does this mean that my application can fail when I receive more packets than I can process, and so there would be no packets available in the pool, or are incoming and outgoing packets handled in different pools? Any best practice on how to handle such a high-load situation?

     

    Edit: As far as I can tell this is the same packet pool that is configured in the configurator. I'm monitoring the available packets by printing g_packet_pool0.nx_packet_pool_available. Is there any reason why one would want to use more than one packet pool, e.g. one for the IP instance  and one for BSD sockets? Apart from a finer granulairty regarding memory usage when different packet sizes are used, I cannot think of any reason.

  • In reply to ChrisS:

    Hi ChrisS,

    Yes, if the device receives valid packets, it can run out of available packets. Of course NetX will stop receving (enqueuing) new packets if it has no available ones in the pool. In this case I suggest using a larger packet pool and try to process packets as soon as possible (and release it).

    The reason of using more packet pools is memory efficiency. Each packet pool contains packets of the same size. Sometimes an application might require larger packets, but sometimes it may need only several bytes to send. E.g. using 1000-byte packet for only several bytes of data will waste noticeable amount of memory.

    Please note that NetX has packet chaining feature, so small packets can be chained to represent larger amount of data. But obviously this will be slightly less efficient than storing all data in one packet.

    Regards,
    adboc