mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Modification to the behaviour of xQueueSend() and xQueueReceive() in the case that a blocked task times out (bug fix).
This commit is contained in:
parent
edc1e01eab
commit
684b802b27
|
@ -240,7 +240,7 @@ size_t xQueueSizeInBytes;
|
||||||
|
|
||||||
signed portBASE_TYPE xQueueSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )
|
signed portBASE_TYPE xQueueSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )
|
||||||
{
|
{
|
||||||
signed portBASE_TYPE xReturn;
|
signed portBASE_TYPE xReturn = pdFAIL;
|
||||||
xTimeOutType xTimeOut;
|
xTimeOutType xTimeOut;
|
||||||
|
|
||||||
/* Make sure other tasks do not access the queue. */
|
/* Make sure other tasks do not access the queue. */
|
||||||
|
@ -338,6 +338,20 @@ xTimeOutType xTimeOut;
|
||||||
taskYIELD();
|
taskYIELD();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We want to check to see if the queue is still full
|
||||||
|
before leaving the critical section. This is to prevent
|
||||||
|
this task placing an item into the queue due to an
|
||||||
|
interrupt making space on the queue between critical
|
||||||
|
sections (when there might be a higher priority task
|
||||||
|
blocked on the queue that cannot run yet because the
|
||||||
|
scheduler gets suspended). */
|
||||||
|
if( pxQueue->uxMessagesWaiting == pxQueue->uxLength )
|
||||||
|
{
|
||||||
|
/* We unblocked but there is no space in the queue,
|
||||||
|
we probably timed out. */
|
||||||
|
xReturn = errQUEUE_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Before leaving the critical section we have to ensure
|
/* Before leaving the critical section we have to ensure
|
||||||
exclusive access again. */
|
exclusive access again. */
|
||||||
vTaskSuspendAll();
|
vTaskSuspendAll();
|
||||||
|
@ -347,6 +361,15 @@ xTimeOutType xTimeOut;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If xReturn is errQUEUE_FULL then we unblocked when the queue
|
||||||
|
was still full. Don't check it again now as it is possible that
|
||||||
|
an interrupt has removed an item from the queue since we left the
|
||||||
|
critical section and we don't want to write to the queue in case
|
||||||
|
there is a task of higher priority blocked waiting for space to
|
||||||
|
be available on the queue. If this is the case the higher priority
|
||||||
|
task will execute when the scheduler is unsupended. */
|
||||||
|
if( xReturn != errQUEUE_FULL )
|
||||||
|
{
|
||||||
/* When we are here it is possible that we unblocked as space became
|
/* When we are here it is possible that we unblocked as space became
|
||||||
available on the queue. It is also possible that an ISR posted to the
|
available on the queue. It is also possible that an ISR posted to the
|
||||||
queue since we left the critical section, so it may be that again there
|
queue since we left the critical section, so it may be that again there
|
||||||
|
@ -370,6 +393,7 @@ xTimeOutType xTimeOut;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
|
}
|
||||||
|
|
||||||
if( xReturn == errQUEUE_FULL )
|
if( xReturn == errQUEUE_FULL )
|
||||||
{
|
{
|
||||||
|
@ -435,7 +459,7 @@ signed portBASE_TYPE xQueueSendFromISR( xQueueHandle pxQueue, const void *pvItem
|
||||||
|
|
||||||
signed portBASE_TYPE xQueueReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait )
|
signed portBASE_TYPE xQueueReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait )
|
||||||
{
|
{
|
||||||
signed portBASE_TYPE xReturn;
|
signed portBASE_TYPE xReturn = pdFAIL;
|
||||||
xTimeOutType xTimeOut;
|
xTimeOutType xTimeOut;
|
||||||
|
|
||||||
/* This function is very similar to xQueueSend(). See comments within
|
/* This function is very similar to xQueueSend(). See comments within
|
||||||
|
@ -468,6 +492,13 @@ xTimeOutType xTimeOut;
|
||||||
taskYIELD();
|
taskYIELD();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )
|
||||||
|
{
|
||||||
|
/* We unblocked but the queue is empty. We probably
|
||||||
|
timed out. */
|
||||||
|
xReturn = errQUEUE_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
vTaskSuspendAll();
|
vTaskSuspendAll();
|
||||||
prvLockQueue( pxQueue );
|
prvLockQueue( pxQueue );
|
||||||
}
|
}
|
||||||
|
@ -475,6 +506,8 @@ xTimeOutType xTimeOut;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( xReturn != errQUEUE_EMPTY )
|
||||||
|
{
|
||||||
taskENTER_CRITICAL();
|
taskENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
|
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
|
||||||
|
@ -498,6 +531,7 @@ xTimeOutType xTimeOut;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
|
}
|
||||||
|
|
||||||
if( xReturn == errQUEUE_EMPTY )
|
if( xReturn == errQUEUE_EMPTY )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue