From owner-freebsd-bugs Fri Feb 1 11:21:51 2002 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 26AAB37B431 for ; Fri, 1 Feb 2002 11:20:01 -0800 (PST) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.6/8.11.6) id g11JK1465701; Fri, 1 Feb 2002 11:20:01 -0800 (PST) (envelope-from gnats) Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 6676837B400 for ; Fri, 1 Feb 2002 11:14:19 -0800 (PST) Received: (from nobody@localhost) by freefall.freebsd.org (8.11.6/8.11.6) id g11JEJF64299; Fri, 1 Feb 2002 11:14:19 -0800 (PST) (envelope-from nobody) Message-Id: <200202011914.g11JEJF64299@freefall.freebsd.org> Date: Fri, 1 Feb 2002 11:14:19 -0800 (PST) From: Yixin To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-1.0 Subject: i386/34536: accept() blocks other threads Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org >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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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