in FreeRTOS_Sockets.c [4787:4957]
void vSocketSelect( SocketSelect_t * pxSocketSet )
{
BaseType_t xRound;
EventBits_t xSocketBits, xBitsToClear;
#if ipconfigUSE_TCP == 1
BaseType_t xLastRound = 1;
#else
BaseType_t xLastRound = 0;
#endif
/* These flags will be switched on after checking the socket status. */
EventBits_t xGroupBits = 0;
for( xRound = 0; xRound <= xLastRound; xRound++ )
{
const ListItem_t * pxIterator;
const ListItem_t * pxEnd;
if( xRound == 0 )
{
pxEnd = ipCAST_CONST_PTR_TO_CONST_TYPE_PTR( ListItem_t, &( xBoundUDPSocketsList.xListEnd ) );
}
#if ipconfigUSE_TCP == 1
else
{
pxEnd = ipCAST_CONST_PTR_TO_CONST_TYPE_PTR( ListItem_t, &( xBoundTCPSocketsList.xListEnd ) );
}
#endif /* ipconfigUSE_TCP == 1 */
for( pxIterator = listGET_NEXT( pxEnd );
pxIterator != pxEnd;
pxIterator = listGET_NEXT( pxIterator ) )
{
FreeRTOS_Socket_t * pxSocket = ipCAST_PTR_TO_TYPE_PTR( FreeRTOS_Socket_t, listGET_LIST_ITEM_OWNER( pxIterator ) );
if( pxSocket->pxSocketSet != pxSocketSet )
{
/* Socket does not belong to this select group. */
continue;
}
xSocketBits = 0;
#if ( ipconfigUSE_TCP == 1 )
if( pxSocket->ucProtocol == ( uint8_t ) FREERTOS_IPPROTO_TCP )
{
/* Check if the socket has already been accepted by the
* owner. If not, it is useless to return it from a
* select(). */
BaseType_t bAccepted = pdFALSE;
if( pxSocket->u.xTCP.bits.bPassQueued == pdFALSE_UNSIGNED )
{
if( pxSocket->u.xTCP.bits.bPassAccept == pdFALSE_UNSIGNED )
{
bAccepted = pdTRUE;
}
}
/* Is the set owner interested in READ events? */
if( ( pxSocket->xSelectBits & ( EventBits_t ) eSELECT_READ ) != ( EventBits_t ) 0U )
{
if( pxSocket->u.xTCP.ucTCPState == ( uint8_t ) eTCP_LISTEN )
{
if( ( pxSocket->u.xTCP.pxPeerSocket != NULL ) && ( pxSocket->u.xTCP.pxPeerSocket->u.xTCP.bits.bPassAccept != pdFALSE_UNSIGNED ) )
{
xSocketBits |= ( EventBits_t ) eSELECT_READ;
}
}
else if( ( pxSocket->u.xTCP.bits.bReuseSocket != pdFALSE_UNSIGNED ) && ( pxSocket->u.xTCP.bits.bPassAccept != pdFALSE_UNSIGNED ) )
{
/* This socket has the re-use flag. After connecting it turns into
* a connected socket. Set the READ event, so that accept() will be called. */
xSocketBits |= ( EventBits_t ) eSELECT_READ;
}
else if( ( bAccepted != 0 ) && ( FreeRTOS_recvcount( pxSocket ) > 0 ) )
{
xSocketBits |= ( EventBits_t ) eSELECT_READ;
}
else
{
/* Nothing. */
}
}
/* Is the set owner interested in EXCEPTION events? */
if( ( pxSocket->xSelectBits & ( EventBits_t ) eSELECT_EXCEPT ) != 0U )
{
if( ( pxSocket->u.xTCP.ucTCPState == ( uint8_t ) eCLOSE_WAIT ) || ( pxSocket->u.xTCP.ucTCPState == ( uint8_t ) eCLOSED ) )
{
xSocketBits |= ( EventBits_t ) eSELECT_EXCEPT;
}
}
/* Is the set owner interested in WRITE events? */
if( ( pxSocket->xSelectBits & ( EventBits_t ) eSELECT_WRITE ) != 0U )
{
BaseType_t bMatch = pdFALSE;
if( bAccepted != 0 )
{
if( FreeRTOS_tx_space( pxSocket ) > 0 )
{
bMatch = pdTRUE;
}
}
if( bMatch == pdFALSE )
{
if( ( pxSocket->u.xTCP.bits.bConnPrepared != pdFALSE_UNSIGNED ) &&
( pxSocket->u.xTCP.ucTCPState >= ( uint8_t ) eESTABLISHED ) &&
( pxSocket->u.xTCP.bits.bConnPassed == pdFALSE_UNSIGNED ) )
{
pxSocket->u.xTCP.bits.bConnPassed = pdTRUE;
bMatch = pdTRUE;
}
}
if( bMatch != pdFALSE )
{
xSocketBits |= ( EventBits_t ) eSELECT_WRITE;
}
}
}
else
#endif /* ipconfigUSE_TCP == 1 */
{
/* Select events for UDP are simpler. */
if( ( ( pxSocket->xSelectBits & ( EventBits_t ) eSELECT_READ ) != 0U ) &&
( listCURRENT_LIST_LENGTH( &( pxSocket->u.xUDP.xWaitingPacketsList ) ) > 0U ) )
{
xSocketBits |= ( EventBits_t ) eSELECT_READ;
}
/* The WRITE and EXCEPT bits are not used for UDP */
} /* if( pxSocket->ucProtocol == FREERTOS_IPPROTO_TCP ) */
/* Each socket keeps its own event flags, which are looked-up
* by FreeRTOS_FD_ISSSET() */
pxSocket->xSocketBits = xSocketBits;
/* The ORed value will be used to set the bits in the event
* group. */
xGroupBits |= xSocketBits;
} /* for( pxIterator ... ) */
} /* for( xRound = 0; xRound <= xLastRound; xRound++ ) */
xBitsToClear = xEventGroupGetBits( pxSocketSet->xSelectGroup );
/* Now set the necessary bits. */
xBitsToClear = ( xBitsToClear & ~xGroupBits ) & ( ( EventBits_t ) eSELECT_ALL );
#if ( ipconfigSUPPORT_SIGNALS != 0 )
{
/* Maybe the socketset was signalled, but don't
* clear the 'eSELECT_INTR' bit here, as it will be used
* and cleared in FreeRTOS_select(). */
xBitsToClear &= ~( ( EventBits_t ) eSELECT_INTR );
}
#endif /* ipconfigSUPPORT_SIGNALS */
if( xBitsToClear != 0U )
{
( void ) xEventGroupClearBits( pxSocketSet->xSelectGroup, xBitsToClear );
}
/* Now include eSELECT_CALL_IP to wakeup the caller. */
( void ) xEventGroupSetBits( pxSocketSet->xSelectGroup, xGroupBits | ( EventBits_t ) eSELECT_CALL_IP );
}