This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RTOS/F28M36P63C2: TI-RTOS sockets not blocking??

Part Number: F28M36P63C2


Tool/software: TI-RTOS

I have been trying to debug a problem that looks as if the TCP sockets are not blocking.  In order to get help I recreated the symptoms from the tcpEcho demo and made minimal modifications.

I started with the basic tcpEcho demo program distributed with TI-RTOS.   The actual demo program runs in an infinite loop returning 0 bytes consuming the available CPU cycles until data is on the socket.  BSD sockets (which it is using) are supposed to block until there is data on the socket, a timeout occurs, or error (with errno set).

To try to work around it I modified the tcpWorker() subroutine to explicitly use MSG_WAITALL as follows:

Void tcpWorker(UArg arg0, UArg arg1)  {
    int clientfd = (int)arg0;
    int bytesRcvd;
    int bytesSent;
    char buffer[TCPPACKETSIZE];
    int notdone = true;

    System_printf("tcpWorker: start clientfd = 0x%x\n", clientfd);

    while (notdone) {
        // should block until TCPPACKETSIZE bytes are received or error.
        bytesRcvd = recv(clientfd, buffer, TCPPACKETSIZE, MSG_WAITALL);
        System_printf ("received %d bytes. errno = %d.\n", bytesRcvd, errno);
        System_flush ();

        bytesSent = send(clientfd, buffer, bytesRcvd, 0);
        if (bytesSent < 0 || bytesSent != bytesRcvd) {
             System_printf("Error: send failed.\n");
             break;
        }
     }
    System_printf("tcpWorker stop clientfd = 0x%x\n", clientfd);
    System_flush();

     close(clientfd);
}

after doing so noted that recv() would continue to return 0 bytes with no errno.

I continued to test it using a standard select() loop implementation (as my actual application uses):

/*
* ======== tcpWorker2 ========
* tcpWorker example modified for standard select() loop.
*/
Void tcpWorker2(UArg arg0, UArg arg1) {
    int clientfd = (int)arg0;
    int bytesRcvd;
    int bytesSent;
    char buffer[TCPPACKETSIZE];
    int notdone = true;

    System_printf("tcpWorker: start clientfd = 0x%x\n", clientfd);

    while (notdone) {
        fd_set read_fds;
        int nfds;

        FD_ZERO(&read_fds);
        FD_SET(clientfd, &read_fds);

        // timeout NULL should block forever but doesn't
        nfds = select(FD_SETSIZE, &read_fds, (fd_set*)0, (fd_set *)0, (struct timeval *) NULL);

        if (nfds <0 ) {
             System_printf ("tcpWorker2: select() error. errno = %d\n", errno);
             break;
        }
        else if (nfds == 0) {
             // Occurs when select timeout is not NULL and no data available
             System_printf ("tcpWorker2: select() timeout.\n");
             continue;
         }
         else {
              System_printf ("tcpWorker2: select() returned %d\n", nfds);
         }

        if (FD_ISSET(clientfd, &read_fds)) {
              bytesRcvd = recv(clientfd, buffer, TCPPACKETSIZE, 0);
              System_printf ("tcpWorker2: received %d bytes. errno = %d.\n", bytesRcvd, errno);
              System_flush();

              bytesSent = send(clientfd, buffer, bytesRcvd, 0);
              if (bytesSent < 0 || bytesSent != bytesRcvd) {
                     System_printf("Error: send failed.\n");
                     break;
               }
          }
    }
    System_printf("tcpWorker stop clientfd = 0x%x\n", clientfd);
    System_flush();

    close(clientfd);
}

In tcpWorker2() example select() continually returns nfds as 1 regardless of if there is data on the port or not and never blocks making the select() call worthless.  

I even tested explicitly setting the timeout to 5 seconds (in a 3rd version) instead of NULL for block forever.

Can someone point me to an actual demo of a select() loop actually blocking?

Thanks,

- Gary