Need to wait for events from a SocketSet and a Queue with the same "wait"

I am new to the forum. Maybe this has been explained before, but I don’t know how to find.

My case is that I want to handle a number of sockets and a queue with a single Task.

I am aware of the SocketSet and have used Queues. If I want to use a xTaskNotifyWait to wait for events from both the Queue and the SocketSet, how would I go about?

Hi and welcome to the forum!

For handling both sockets and queue events in a single task, here are a few approaches in my mind:

  1. Using socket rx callback and translate that into task notify:
// In your socket callback:
RETURN_TYPE socket_rx_callback( ... )
{
    xTaskNotify( xEventTaskHandle, SOCKET_EVENT, eSetBits, NULL );
    /* ... */
}

// Queue send wrapper
BaseType_t queue_event_send( ... )
{
    BaseType_t xResult = xQueueSend(xQueue, pvItemToQueue, xTicksToWait);
    if (xResult == pdPASS)
    {
        xTaskNotify(xEventTaskHandle, QUEUE_EVENT, eSetBits);
    }
    return xResult;
}

// Your event handling task
void vEventHandlingTask(void *pvParameters)
{
    uint32_t ulNotificationValue;
    
    while(1)
    {
        if( xTaskNotifyWait(0x00, ULONG_MAX, &ulNotificationValue, portMAX_DELAY) == pdTRUE )
        {
            if( ( ulNotificationValue & SOCKET_EVENT) != 0 )
            {
                // Handle socket data
            }

            if( ( ulNotificationValue & QUEUE_EVENT ) != 0 )
            {
                // Handle queue data
            }
        }
    }
}
  1. Polling with short timeout. Note that it has at most 10ms delay to handle queue event because of timeout of select in below example. I don’t recommend to set both timeout to 0 because it makes this task busy polling.
void vEventHandlingTask(void *pvParameters)
{
    while(1)
    {
        BaseType_t xSocketActivity = select( xSocketSet, 10ms );
        
        if(xSocketActivity > 0 )
        {
            // Handle socket events
        }
        
        // Check queue
        while( xQueueReceive(xQueue, &data, 0) == pdPASS )
        {
            // Handle queue data
        }
    }
}

Thank you.

1 Like

Approach 1 suggested by @ActoryOu is more efficient as it does not consume any more CPU cycles than necessary.

Thank you for the reply! I will try out the first approach. /Joakim

I agree and will try the the first!

I tried something like and it works! Thank!

while the solution is perfectly ok (except that the control flow favors socket events over queue events), what is the additional notification detour used for? Why could your socket callback not post another (tagged) event directly to the queue?