Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 Feb 2002 13:16:31 -0800 (PST)
From:      ccloud <ccloud@inteqrx.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   misc/34673: Second call to select() waits ~100ms before data available
Message-ID:  <200202062116.g16LGVC52299@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         34673
>Category:       misc
>Synopsis:       Second call to select() waits ~100ms before data available
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Feb 06 13:20:00 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     ccloud
>Release:        
>Organization:
Inteq
>Environment:
FreeBSD switch.in.net 4.2-RELEASE FreeBSD 4.2-RELEASE #8: Tue Aug 21 14:55:44
 CDT 2001     root@switch1.in.net:/usr/src/sys/compile/SWITCH  i386
>Description:
     I've inherited a tradition client/server application.  The client connects to the server, receives 2 messages from the server, then goes aways.  The client sits in the select() waiting for the messages.  The first message is received by the client within 1ms of when the sever sent it.  The client then calls select() again (almost immediately).  The sever sends the second message but the select returns only about 100ms from the receipt of the first message.  

Here are some timestamps of the programs below:
Server:
Waiting for connection
TIME: 1013027320.232152 send
TIME: 1013027320.232411 send done
TIME: 1013027320.262219 send
TIME: 1013027320.262310 send done

Client:
TIME: 1013027320.219166 getIo select
TIME: 1013027320.232327 getIo select done
Read data 20
TIME: 1013027320.252139 getIo select
TIME: 1013027320.332200 getIo select done
Read data 370

Notice the server sent the second message at .262219 but the client didn't receive it until .332200 about 100ms after the first message was received at .232327
Both programs are the only programs running on the same machine.
>How-To-Repeat:
*************************** CLIENT ********************************
static struct timeval timeit;
#define TIMEITHERE(STR)  gettimeofday(&timeit,0); \
fprintf(stderr,"TIME: %ld.%.6ld %s\n", timeit.tv_sec, timeit.tv_usec,STR);

/*
** connect to remote host
*/
int connectTo(host, service, attempts)
char	*host;
char	*service;
int	attempts;
{

	int			l_socket;	/* listen socket */
	u_short			s_port;		/* service port number */
	struct in_addr		host_ip;	/* remote host IP - "in.h" */
	struct sockaddr_in	s_name;		/* socket address - "in.h" */
	int			i;
	int			ret;


	s_port = htons(atoi(service));
	if ((ret=inet_aton(host, &host_ip)) == 0) {
		return(-1);
	}

	bzero((char *) &s_name, sizeof(s_name));
	s_name.sin_family = AF_INET;
	s_name.sin_port = s_port;
	s_name.sin_addr.s_addr = host_ip.s_addr;

	signal(SIGTERM, SIG_DFL);
	signal(SIGINT, SIG_DFL);
	signal(SIGQUIT, SIG_IGN);
	signal(SIGALRM, SIG_IGN);

	/*
	** get a socket
	*/
	for (i=0, ret=-1; i<10 && ret<0; ++i) {

		if ((l_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
			return(-1);
		}
		ret=connect(l_socket, (struct sockaddr *)&s_name, sizeof(s_name));
		if (ret < 0) {
			fprintf(stderr,"Error(connect): %s\n", strerror(errno));
			close(l_socket);
			usleep(100*1000);
		}
	}
	if (ret < 0) return(-1);
	return(l_socket);
}



int getIo(fd ,buf, len)
int	fd;			/* input socket file descriptor */
char	*buf;			/* buffer to hold data for transfer */
int	len;			/* length of data or len og buffer */
{
	fd_set		fdset;	/* file descptors set */
	int		event;	/* event on the given socket */
	int		ret;
	struct timeval	timeout;

	timeout.tv_sec  = (time_t)1000;
	timeout.tv_usec = (time_t)0;


	FD_ZERO( &fdset );
	FD_SET(fd, &fdset);

	TIMEITHERE("getIo select");
	event = select(fd+1, &fdset, NULL, NULL, &timeout);
	TIMEITHERE("getIo select done");

	if (event == 0) {
		fprintf(stderr, "Timed out\n");
		sleep(1);
		return(-1);
	}
	if (event < 0) {
		fprintf(stderr, "SELECT ERROR - errno %d\n",errno);
		return(-1);
	}
	if (! FD_ISSET(fd, &fdset)) {
		fprintf(stderr, "Not our socket ????\n");
		usleep(5*1000);
	}

	buf[0] = '\0';

	ret = read(fd, buf, len);

	if (ret < 0) {
		fprintf(stderr, "READ ERROR errno=%d\n",errno);
	} else if (ret == 0) {
		fprintf(stderr, "READ ERROR zero\n");
	} else {
	        fprintf(stderr, "Read data %d\n",ret);
		buf[ret] = '\0';
	}

	return(ret);
}


int main( int argv, char* argc[] ) 
{
	char buf[1024];
	int fd;

 	fd = connectTo("192.168.100.119", "9801");

	getIo(fd, buf, 20);
	usleep(10*1000);
	getIo(fd, buf, 370);

	sleep(5);
	return 0;
}

****************************** SERVER *******************************

static struct timeval timeit;
#define TIMEITHERE(STR)  gettimeofday(&timeit,0); \
fprintf(stderr,"TIME: %ld.%.6ld %s\n", timeit.tv_sec, timeit.tv_usec,STR);


/*
** SEND IO over connected socket
*/
int sendIo(fd ,buf, len)
int	fd;			/* input socket file descriptor */
char	*buf;			/* buffer to hold data for transfer */
int	len;			/* length of data or len og buffer */
{
	int		ret;

TIMEITHERE("send");
	ret = write(fd, buf, len);
TIMEITHERE("send done");
	if ( ret < 0 ) {
		fprintf(stderr, "WRITE ERORR - errno %d\n",errno);
	}
	return(ret);
}



int doserver(host, service, attempts)
char	*host;
char	*service;
int	attempts;
{
	int             	l_socket;	/* listen socket */
	int			a_socket;	/* accept socket */
	int             	in_fd;	/* input/output socket */
	u_short			s_port;		/* service port number */
	struct sockaddr_in	s_name;		/* binding socket name */ 
	struct sockaddr_in	c_name;		/* connected socket name */
	int			on = 1;		/* socket level opt value on */
	char			*oval = (char *) &on;
	int			osz=sizeof(on);	/* socket option value size */
	int			olvl=SOL_SOCKET;/* socket option level */
	int			i, j, ret;
	struct in_addr		host_ip;	/* remote host IP - "in.h" */


	s_port = htons(atoi(service));
	if ((ret=inet_aton(host, &host_ip)) == 0) {
		return(-1);
	}

	bzero((char *) &s_name, sizeof(s_name));
	s_name.sin_family = AF_INET;
	s_name.sin_port = s_port;
	s_name.sin_addr.s_addr = host_ip.s_addr;


	do {
		if ((l_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
			fprintf(stderr,"Error(socket): %s", strerror(errno));
			exit(-1);
		}
		if (setsockopt(l_socket, olvl, SO_KEEPALIVE, oval, osz) < 0) {
			fprintf(stderr,"Error(setsock1): %s", strerror(errno));
			exit(-1);
		}
		if (setsockopt(l_socket, olvl, SO_REUSEADDR, oval, osz) < 0) {
			fprintf(stderr,"Error(setsock2): %s", strerror(errno));
			exit(-1);
		}
		if (setsockopt(l_socket, olvl, SO_REUSEPORT, oval, osz) < 0) {
			fprintf(stderr,"Error(setsock3): %s", strerror(errno));
			exit(-1);
		}

		ret=bind(l_socket,(struct sockaddr *)&s_name,sizeof(s_name));
		if (ret<0) {
			fprintf(stderr,"Error(bind): %s", strerror(errno));
			exit(-1);
		}

		listen(l_socket, 0);

		j = 0;
		do {
			fprintf(stderr,"Waiting for connection\n");
			i = sizeof(c_name);
			a_socket=accept(l_socket,(struct sockaddr *)&c_name,&i);

			if (a_socket >= 0) {
			   close(l_socket);
			} else {
			   ++j;
			   fprintf(stderr,"Error(accept): %s", strerror(errno));
			   usleep(1000);
			}
		} while (a_socket < 0 && j < 100);

		if (a_socket < 0) {
			ret = -1;
			continue;
		}

	} while(a_socket < 0);

	return(a_socket);
}






int main( int argv, char* argc[] ) 
{
	char buf[1024];
	int fd;
	int ret,i;

 	fd = doserver("192.168.100.119", "9801");
	sprintf(buf,"11111222223333344444");
	usleep(10*1000);
	ret = sendIo(fd, buf, strlen(buf));

	usleep(20*1000);
	buf[0] = '\0';
	for(i=0; i<37; i++)
  		strcat(buf,"0123456789");
	ret = sendIo(fd, buf, strlen(buf));

	sleep(1);
}





>Fix:
      
>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200202062116.g16LGVC52299>