Modification to the behaviour of xQueueSend() and xQueueReceive() in the case that a blocked task times out (bug fix).

pull/4/head
Richard Barry 18 years ago
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…
Cancel
Save