misc/41331: Pthread library open sets O_NONBLOCK flag andcauses unnecessary EAGAIN errors especially with /dev/stdout.

Dorr H. Clark dclark at applmath.scu.edu
Mon May 5 20:40:32 PDT 2003

The following reply was made to PR misc/41331; it has been noted by GNATS.

From: "Dorr H. Clark" <dclark at applmath.scu.edu>
To: freebsd-gnats-submit at FreeBSD.org, alo at iki.fi
Subject: Re: misc/41331: Pthread library open sets O_NONBLOCK flag and causes 
 unnecessary EAGAIN errors especially with /dev/stdout.
Date: Mon, 05 May 2003 20:37:20 -0700

 42943 is a duplicate of 41331, or at best an extended symptom.
 First of all, both 41331 and 42943 occur on purpose, 
 and this is not a regression introduced by some other change,
 it is part of the original pthread code.
 We believe that this behavior is a side effect of the FreeBSD
 threads implementation, and that 41331 and 42943 are normal behavior.
 These bugs can only plausibly be addressed by rearchitecting 
 the threads implementation, possibly in the context of 5.x.
 In FreeBSD, the pthread implementation is as a user-level thread
 in other words, all threads execute in the context of a single process, 
 and the thread scheduler is hidden in the threaded version of libc.
 As a side-effect of this implementation, when a blocking system call 
 is executed, the kernel only knows about the process, and 
 this results in all the threads being blocked.
 To avoid blocking the entire thread group, the stdin, stdout and stderr 
 file descriptors are made non-blocking.
 Note that while these two bugs were filed against the recent 4.x
 there is nothing new in this area.  The code governing this behavior
 has 2.x and 3.x labels in the CVS tree.
 In 41331, there is a test program, and as part of our investigation
 we tried this program on both Solaris and Linux.  Neither one exhibits
 the 41331 behavior, however readers who are familiar with the threads
 implementation will realize that these are three radically different
 threads implementations, accounting for the discrepancy.
 If the 41331 behavior is intolerable, there are two possible approaches,
 either wait for a pthreads implementation on top of the kernel threads 
 in FreeBSD 5.0 or install the linuxthreads port, which simulates the
 way of handling threads as separate processes. 
 NOTE:  The following code excerpt is from 4.7-STABLE !
 Here are two code snips which control this behavior.
 code snip from libc_r/uthread/pthread_private.h :
  * Standard I/O file descriptors need special flag treatment since
  * setting one to non-blocking does all on *BSD. Sigh. This array
  * is used to store the initial flag settings.
 SCLASS int      _pthread_stdio_flags[3];
 code snip from uthread_fd.c :
                         /* Check if a stdio descriptor: */
                         if ((fd < 3) && (_pthread_stdio_flags[fd] !=
                                  * Use the stdio flags read by
                                  * _pthread_init() to avoid
                                  * mistaking the non-blocking
                                  * flag that, when set on one
                                  * stdio fd, is set on all stdio
                                  * fds.
                                 entry->flags = _pthread_stdio_flags[fd];
                          * Make the file descriptor non-blocking.
                          * This might fail if the device driver does
                          * not support non-blocking calls, or if the
                          * driver is naturally non-blocking.
                         saved_errno = errno;
                         _thread_sys_fcntl(fd, F_SETFL,
                             entry->flags | O_NONBLOCK);
                         errno = saved_errno;
 Rashmi Venkatesh, engineer
 Dorr H. Clark, advisor
 COEN 284 - Operating Systems Case Study 
 Santa Clara University, 
 Santa Clara CA.

More information about the freebsd-bugs mailing list