From owner-freebsd-bugs Thu Nov 8 13:10:16 2001 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 08CF937B419 for ; Thu, 8 Nov 2001 13:10:04 -0800 (PST) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.4/8.11.4) id fA8LA4q71213; Thu, 8 Nov 2001 13:10:04 -0800 (PST) (envelope-from gnats) Received: from starbug.ugh.net.au (starbug.ugh.net.au [203.31.238.37]) by hub.freebsd.org (Postfix) with ESMTP id 2CA1837B405 for ; Thu, 8 Nov 2001 13:00:46 -0800 (PST) Received: by starbug.ugh.net.au (Postfix, from userid 1000) id 4504BA842; Fri, 9 Nov 2001 08:00:42 +1100 (EST) Message-Id: <20011108210042.4504BA842@starbug.ugh.net.au> Date: Fri, 9 Nov 2001 08:00:42 +1100 (EST) From: Andrew Reply-To: Andrew To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.113 Subject: bin/31860: read wont timeout on sockets if using 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: 31860 >Category: bin >Synopsis: read wont timeout on sockets if using 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: Thu Nov 08 13:10:00 PST 2001 >Closed-Date: >Last-Modified: >Originator: Andrew >Release: FreeBSD 4.4-STABLE i386 >Organization: UgH! >Environment: System: FreeBSD starbug.ugh.net.au 4.4-STABLE FreeBSD 4.4-STABLE #3: Sun Oct 7 21:30:09 EST 2001 andrew@starbug.ugh.net.au:/usr/obj/usr/src/sys/STARBUG i386 >Description: I have a program that creates a TCP socket and listens for incoming connections. After calling accept it uses setsockopt and the SO_RCVTIMEO and SO_SNDTIMEO options so that reads will timeout if no data is received for a while. This works flawlessly unless the program is compiled with -pthread (the program doesn't actually use any pthread_* functions). If compiled with threads then a call to read will block forever. >How-To-Repeat: This is an example program that works as expected unless -pthread is passed to the compiler (as expected means read times out after 15 seconds). You can also get this program from http://www.ugh.net.au/~andrew/tmp/setsockopt.c in case it gets mangled in transit. #include #include #include #include #include #include #include #include #include #include #include int main(int argc, char *argv[]) { char buffer[1024]; int listening_fd, connection_fd, port, size; struct sockaddr_in local_address, remote_address; struct timeval tv; if (argc != 2) { fprintf(stderr, "usage: %s port\n", getprogname()); exit(1); } else { port = atoi(argv[1]); } /* create socket */ if ((listening_fd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { err(1, "socket"); } /* allow us to rebind even if old clients are still hanging around */ size = 1; /* borrow memory for a second */ if (setsockopt(listening_fd, SOL_SOCKET, SO_REUSEADDR, &size, sizeof(size)) != 0) { err(1, "setsockopt"); } /* describe our end of the connection */ bzero(&local_address, sizeof(local_address)); local_address.sin_family = AF_INET; local_address.sin_addr.s_addr = htonl(INADDR_ANY); local_address.sin_port = htons(port); /* bind the socket to the address */ if (bind(listening_fd, (struct sockaddr *)&local_address, sizeof(local_address)) == -1) { err(1, "bind"); } /* make it a listening port */ if (listen(listening_fd, -1) != 0) { err(1, "listen"); } /* accept connections */ for (;;) { size = sizeof(remote_address); if ((connection_fd = accept(listening_fd, (struct sockaddr *)&remote_address, &size)) == -1) { err(1, "accept"); } printf("connected...\n"); /* set up timeouts */ tv.tv_sec = 15L; tv.tv_usec = 0L; if (setsockopt(connection_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) != 0) { err(1, "setsockopt"); } if (setsockopt(connection_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) != 0) { err(1, "setsockopt"); } /* do a bit of reading and writing */ #define STRING "hello\n" if (write(connection_fd, STRING, sizeof(STRING)) == -1) { err(1, "write"); } #undef STRING if (read(connection_fd, buffer, sizeof(buffer)) == -1) { warn("read"); goto failure; } else { printf("received %s", buffer); } #define STRING "goodbye\n" if (write(connection_fd, STRING, sizeof(STRING)) == -1) { err(1, "write"); } #undef STRING failure: if (close(connection_fd) == -1) { err(1, "close"); } printf("disconnected...\n"); } return 0; } >Fix: >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message