From andrew@ugh.net.au  Thu Nov  8 13:00:47 2001
Return-Path: <andrew@ugh.net.au>
Received: from starbug.ugh.net.au (starbug.ugh.net.au [203.31.238.37])
	by hub.freebsd.org (Postfix) with ESMTP id 2CA1837B405
	for <FreeBSD-gnats-submit@freebsd.org>; 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 <andrew@ugh.net.au>
Reply-To: Andrew <andrew@ugh.net.au>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: read wont timeout on sockets if using threads
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         31860
>Category:       bin
>Synopsis:       read wont timeout on sockets if using threads
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Nov 08 13:10:00 PST 2001
>Closed-Date:    Sun Dec 01 12:27:32 PST 2002
>Last-Modified:  Sun Dec 01 12:27:32 PST 2002
>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 <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>

#include <netinet/in.h>
#include <arpa/inet.h>

#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

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:

From: "Mr. Feed" <mrfeed@yahoo.com>
To: freebsd-gnats-submit@FreeBSD.org, andrew@ugh.net.au
Cc: mrfeed@yahoo.com
Subject: Re: bin/31860: read wont timeout on sockets if using threads
Date: Sat, 29 Dec 2001 09:53:50 -0800

 i think this problem never get solved since FreeBSD 4.1 - I have the same problem in FreeBSD 4.3 stable, i.e. set timeout has not effects whatsoever if linked with libc_r. Do you guys have any plan to do something about it?
 
 thanks.
 
 
 _________________________________________________________
 Do You Yahoo!?
 Get your free @yahoo.com address at http://mail.yahoo.com
 

From: Maxim Konovalov <maxim@macomnet.ru>
To: freebsd-gnats-submit@FreeBSD.org, <andrew@ugh.net.au>
Cc:  
Subject: Re: bin/31860: read wont timeout on sockets if using threads
Date: Wed, 23 Jan 2002 14:41:51 +0300 (MSK)

 This PR is duplicated with misc/20861:
 
 http://www.FreeBSD.org/cgi/query-pr.cgi?pr=31860
 
 -- 
 Maxim Konovalov, MAcomnet, Internet-Intranet Dept., system engineer
 phone: +7 (095) 796-9079, mailto: maxim@macomnet.ru
 
State-Changed-From-To: open->closed 
State-Changed-By: iedowse 
State-Changed-When: Sun Dec 1 12:27:09 PST 2002 
State-Changed-Why:  

Duplicate of PR misc/20861. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=31860 
>Unformatted:
