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 xReturn;
|
||||
signed portBASE_TYPE xReturn = pdFAIL;
|
||||
xTimeOutType xTimeOut;
|
||||
|
||||
/* Make sure other tasks do not access the queue. */
|
||||
|
@ -338,6 +338,20 @@ xTimeOutType xTimeOut;
|
|||
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
|
||||
exclusive access again. */
|
||||
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
|
||||
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
|
||||
|
@ -370,6 +393,7 @@ xTimeOutType xTimeOut;
|
|||
}
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
|
||||
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 xReturn;
|
||||
signed portBASE_TYPE xReturn = pdFAIL;
|
||||
xTimeOutType xTimeOut;
|
||||
|
||||
/* This function is very similar to xQueueSend(). See comments within
|
||||
|
@ -468,6 +492,13 @@ xTimeOutType xTimeOut;
|
|||
taskYIELD();
|
||||
}
|
||||
|
||||
if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )
|
||||
{
|
||||
/* We unblocked but the queue is empty. We probably
|
||||
timed out. */
|
||||
xReturn = errQUEUE_EMPTY;
|
||||
}
|
||||
|
||||
vTaskSuspendAll();
|
||||
prvLockQueue( pxQueue );
|
||||
}
|
||||
|
@ -475,6 +506,8 @@ xTimeOutType xTimeOut;
|
|||
}
|
||||
}
|
||||
|
||||
if( xReturn != errQUEUE_EMPTY )
|
||||
{
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
|
||||
|
@ -498,6 +531,7 @@ xTimeOutType xTimeOut;
|
|||
}
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
|
||||
if( xReturn == errQUEUE_EMPTY )
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue