void vSocketSelect()

in amazon-freertos/lib/FreeRTOS-Plus-TCP/source/FreeRTOS_Sockets.c [3415:3575]


	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;
		pxSocketSet->pxSocket = NULL;

		for( xRound = 0; xRound <= xLastRound; xRound++ )
		{
			const ListItem_t *pxIterator;
			const MiniListItem_t *pxEnd;
			if( xRound == 0 )
			{
				pxEnd = ( const MiniListItem_t* )listGET_END_MARKER( &xBoundUDPSocketsList );
			}
		#if ipconfigUSE_TCP == 1
			else
			{
				pxEnd = ( const MiniListItem_t* )listGET_END_MARKER( &xBoundTCPSocketsList );
			}
		#endif /* ipconfigUSE_TCP == 1 */
			for( pxIterator = ( const ListItem_t * ) ( listGET_NEXT( pxEnd ) );
				 pxIterator != ( const ListItem_t * ) pxEnd;
				 pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator ) )
			{
				FreeRTOS_Socket_t *pxSocket = ( 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 == 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 & eSELECT_READ ) != 0 )
						{
							if( pxSocket->u.xTCP.ucTCPState == eTCP_LISTEN )
							{
								if( ( pxSocket->u.xTCP.pxPeerSocket != NULL ) && ( pxSocket->u.xTCP.pxPeerSocket->u.xTCP.bits.bPassAccept != 0 ) )
								{
									xSocketBits |= 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
								aconnected socket. Set the READ event, so that accept() will be called. */
								xSocketBits |= eSELECT_READ;
							}
							else if( ( bAccepted != 0 ) && ( FreeRTOS_recvcount( pxSocket ) > 0 ) )
							{
								xSocketBits |= eSELECT_READ;
							}
						}
						/* Is the set owner interested in EXCEPTION events? */
						if( ( pxSocket->xSelectBits & eSELECT_EXCEPT ) != 0 )
						{
							if( ( pxSocket->u.xTCP.ucTCPState == eCLOSE_WAIT ) || ( pxSocket->u.xTCP.ucTCPState == eCLOSED ) )
							{
								xSocketBits |= eSELECT_EXCEPT;
							}
						}

						/* Is the set owner interested in WRITE events? */
						if( ( pxSocket->xSelectBits & eSELECT_WRITE ) != 0 )
						{
							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 >= eESTABLISHED ) &&
									( pxSocket->u.xTCP.bits.bConnPassed == pdFALSE_UNSIGNED ) )
								{
									pxSocket->u.xTCP.bits.bConnPassed = pdTRUE_UNSIGNED;
									bMatch = pdTRUE;
								}
							}

							if( bMatch != pdFALSE )
							{
								xSocketBits |= eSELECT_WRITE;
							}
						}
					}
					else
				#endif /* ipconfigUSE_TCP == 1 */
				{
					/* Select events for UDP are simpler. */
					if( ( ( pxSocket->xSelectBits & eSELECT_READ ) != 0 ) &&
						( listCURRENT_LIST_LENGTH( &( pxSocket->u.xUDP.xWaitingPacketsList ) ) > 0U ) )
					{
						xSocketBits |= 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 ) & 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 != 0 )
		{
			xEventGroupClearBits( pxSocketSet->xSelectGroup, xBitsToClear );
		}

		/* Now include eSELECT_CALL_IP to wakeup the caller. */
		xEventGroupSetBits( pxSocketSet->xSelectGroup, xGroupBits | eSELECT_CALL_IP );
	}