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