Subject: pkg/12650: unproven-pthreads mishandles simultaneous select + read on same fd
To: None <gnats-bugs@gnats.netbsd.org>
From: None <gson@nominum.com>
List: netbsd-bugs
Date: 04/13/2001 17:18:55
>Number:         12650
>Category:       pkg
>Synopsis:       unproven-pthreads mishandles simultaneous select + read on same fd
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Apr 13 17:20:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Andreas Gustafsson
>Release:        20010412
>Organization:
Nominum, Inc.
>Environment:
System: NetBSD trebuchet.rc.vix.com 1.5S NetBSD 1.5S (TREBUCHET) #0: Thu Mar 8 16:36:26 PST 2001 gson@trebuchet.rc.vix.com:/usr/src/sys/arch/i386/compile/TREBUCHET i386
Architecture: i386
Machine: i386
>Description:

NetBSD's unproven-pthreads-0.17 package exhibits the following behavior:

   If one thread is blocking in select() waiting for input on a file
   descriptor, and another thread then issues a nonblocking read on
   that same file descriptor, the latter thread blocks.

>How-To-Repeat:

The following test program illustrates the problem.  It should output

  calling select()
  <2 second pause here>
  calling read()
  read() exited
  <program blocks waiting for input>

but instead it outputs

  calling select()
  <2 second pause here>
  calling read()
  <program blocks waiting for input>

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	Makefile
#	test.c
#
echo x - Makefile
sed 's/^X//' >Makefile << 'END-of-Makefile'
XCC=/usr/pkg/pthreads/bin/pgcc
X
Xtest: test.c
X	$(CC) $(CFLAGS) test.c -o test
X
END-of-Makefile
echo x - test.c
sed 's/^X//' >test.c << 'END-of-test.c'
X
X#include <fcntl.h>
X#include <pthread.h>
X#include <sys/types.h>
X#include <sys/time.h>
X#include <unistd.h>
X
Xpthread_t thread1;
X
Xvoid *
Xf1(void *arg) {
X	char buf[1];
X
X	sleep(2);
X	
X	printf("calling read()\n");
X	read(0, buf, sizeof(buf));
X	printf("read() exited\n");	
X}
X
Xmain() {
X	int ret;
X	fd_set r, w, e;
X	int flags = O_NONBLOCK;
X	
X	ret = pthread_create(&thread1, NULL, f1, NULL);
X	if (ret != 0)
X		abort();
X
X	fcntl(0, F_SETFL, &flags);
X
X	FD_ZERO(&r);
X	FD_ZERO(&w);
X	FD_ZERO(&e);
X
X	FD_SET(0, &r);
X
X	printf("calling select()\n");
X
X	select(1, &r, &w, &e, NULL);
X
X	printf("select() returned\n");	
X}
X
END-of-test.c
exit

>Fix:

Unknown.
>Release-Note:
>Audit-Trail:
>Unformatted: