Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 1 Feb 2002 11:14:19 -0800 (PST)
From:      Yixin <yxpan@yahoo.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   i386/34536: accept() blocks other threads
Message-ID:  <200202011914.g11JEJF64299@freefall.freebsd.org>

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

>Number:         34536
>Category:       i386
>Synopsis:       accept() blocks other threads
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Feb 01 11:20:01 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Yixin
>Release:        4.4
>Organization:
SLMsoft
>Environment:
FreeBSD freebsd.slm.com 4.4-RELEASE FreeBSD 4.4-RELEASE #3: Wed Jan 30 13:38:55 EST 2002 root@freebsd.slm.com:/usr/src/sys/compile/MYKERNEL i386     
>Description:
I created a simple program: main thread listens to a port, and child threads serve the requests. If main thread uses accept() to wait for request, the new thread can not get scheduled. But if main thread uses select() to wait for request, it works fine.      
>How-To-Repeat:
/* This is just a test program
 * Compile:
 *	cc -o thread thread.c -pthread
 * Test:
 *	./thread 90
 *	telnet localhost 90
 */
#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <sys/resource.h>
#include <netinet/in.h>
#include <netdb.h>
#include <syslog.h>
#include <errno.h>
#include <signal.h>




void * srv(void *arg){
	int fd=(int)arg;
	char buff[100];
	int count;
	struct sockaddr_in saddr, daddr;
	int length;

	syslog(LOG_NOTICE, "Begin to read");
	count=read(fd, buff, 10);
	close(fd);
	syslog(LOG_NOTICE, "Begin to exit");
}



main(int argc, char *argv[]){
    int sock, newsock, length, port,pid, i;
    struct sockaddr_in addr, daddr;
    pthread_t ptid;
    pthread_attr_t tattr;

    if(argc==1) {
	printf("Usage:\n	%s Port\n", argv[0]);
	exit(1);
    }

    port=atoi(argv[1]);
    if(port==0){
	printf("Illegal Port:%s\n", argv[1]);
	exit(1);
    }
	
    sock=socket(AF_INET, SOCK_STREAM,0);
    if(sock < 0){
		perror("Opening stream socket");
		exit(1);
    }

    bzero(&addr, sizeof(addr));
    addr.sin_family=AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_port = htons(port);
    if(bind(sock, (struct sockaddr *)&addr, sizeof addr) == -1){
		perror("Binding stream socket");
		exit(1);
    };

    bzero(&addr, sizeof(addr));
    i = sizeof(addr);
    if(getsockname(sock, (struct sockaddr *)&addr, &i) < 0){
	perror("getsockname");
	exit(1);
    }

    if(listen(sock, 5) == -1){
	perror("Listening stream socket");
	exit(1);
    };

    if(fork()){
	sleep(2);
	exit(0);
    }

    pthread_attr_init(&tattr);
    pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
    pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM);

    setsid();

#define USE_POLL

#ifdef USE_POLL
    {
	fd_set fdset;
	struct timeval timeout;

	while(1){
	    FD_ZERO(&fdset);
	    FD_SET(sock, &fdset);
	    timeout.tv_usec = 0;
	    timeout.tv_sec = 10;

	    i=select(sock+1, &fdset, NULL, NULL, &timeout);
	    if(i==0)
			continue;
	    else if(i < 0){
				syslog(LOG_NOTICE, "select: %m");
				continue;
	    };
	    length = sizeof(daddr);
	    newsock=accept(sock, (struct sockaddr *)&daddr, &length);
	    if(newsock < 0){
			syslog(LOG_NOTICE, "accept: %m");
			continue;
	    }
	    if(pthread_create(&ptid, &tattr, srv, (void *)newsock)){
	    	syslog(LOG_NOTICE, "pthread_create() failed: %m");
		close(newsock);
	    }
	}
    }
#else
    while((newsock=accept(sock, (struct sockaddr *)&daddr, (length=sizeof daddr, &length))) != -1){
	syslog(LOG_NOTICE, "Main Thread is going to start a new thread");
	if(pthread_create(&ptid, &tattr, srv, (void *)newsock)){
	    syslog(LOG_NOTICE, "pthread_create() failed: %m");
	    close(newsock);
	}
    }
#endif

    /* never reached */
    close(sock);
}


      
>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?200202011914.g11JEJF64299>