Non blocking socket design: FreeRTOS_FD_ISSET and read/write/exception event granularity

willschmid wrote on Monday, May 06, 2019:

As part of my non blocking (asynchronous) socket application, I need to know what type of event FreeRTOS_select generated for a particular socket.

FreeRTOS_FD_ISSET simply returns true if any event flag is set. How can I find out what type of event was generated for the socket?

heinbali01 wrote on Tuesday, May 07, 2019:

Willhelm, the code in FreeRTOS_FD_ISSET() can be read as follows:

if xSocket is part of ( connected to ) xSocketSet, the select event mask in xSocketBits will be returned.

This mask has 4 bits, more or less comparable to the BSD select() :

    eSELECT_READ    /* the socket has data in its RX buffer */
    eSELECT_WRITE   /* the socket has space in its TX buffer */
    eSELECT_EXCEPT  /* the socket has had an exception (connection closed) */
    eSELECT_INTR    /* and API call got interrupted after FreeRTOS_SignalSocket() was called. */

eSELECT_READ has a second use: when a socket in listening mode receives a new connection, the event is generated.
Likewise, eSELECT_WRITE is generated as soon as connect() leads to a TCP connection.

So for listening “server” sockets, it is important to enable eSELECT_READ, and for a connecting “client” sockets, it is recommended to enable the eSELECT_WRITE event.

When FreeRTOS_send() returns less bytes than expected, or the error -pdFREERTOS_ERRNO_ENOSPC, it is good to enable eSELECT_WRITE for that socket, and get woken up as soon as there is space.
But eSELECT_WRITE can be nasty: when it occurs you either send data, or disable it. If not, it will come back again and again. Nothing peculiar here: the same behaviour can be expected on a PC.

Inheritance: when a server socket receives a new connection, the new connection will automatically belong the the same select group, and it will have the eSELECT_READ and eSELECT_EXCEPT bits set.

willschmid wrote on Tuesday, May 07, 2019:

Thank you for your detailed explanation Hein. I am looking at the documentation and I am not sure how I missed reading the details.