threads/72429: threads blocked in stdio (fgets, etc) are not cancellable in 5.3 (works in 4.x)

Mark Gooderum mark at verniernetworks.com
Thu Oct 7 15:40:41 PDT 2004


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

From: Mark Gooderum <mark at verniernetworks.com>
To: Daniel Eischen <deischen at gdeb.com>
Cc: freebsd-gnats-submit at freebsd.org, freebsd-threads at freebsd.org,
	archie at dellroad.org
Subject: Re: threads/72429: threads blocked in stdio (fgets, etc) are not
 cancellable in 5.3 (works in 4.x)
Date: Thu, 07 Oct 2004 17:36:44 -0500

 This is a multi-part message in MIME format.
 --------------080409080603080600050704
 Content-Type: text/plain; charset=us-ascii; format=flowed
 Content-Transfer-Encoding: 7bit
 
 Uncle.  Okay - you're right, sigh.
 
 It's not so much that we're using fgets() as many/most C based parsing 
 libraries use stdio, bleh.
 
 As for why libc_r is cancellable...
 
 In 4.x  _foo() sets the cancellation state and calls __foo() (for read, 
 write, et.al), in 5.3 it's reversed. 
 --
 Mark
 
 >On Thu, 7 Oct 2004, Mark Gooderum wrote:
 >
 >  
 >
 >>But this is a major change in behavior from FreeBSD 4 and also a
 >>difference from Linux.  I'm not a Linux bigot at all but there is a
 >>recurring theme that XX threaded apps works on Linux but is unstable on
 >>FreeBSD and these sort of major behavior deltas contribute to the
 >>perception of FreeBSD threading as unstable by some.
 >>    
 >>
 >
 >If you want to be portable, you should be using select() or
 >poll().  It's not like there is no portable way of doing
 >what you want, and in fact relying on fgets() to be cancellable
 >is not portable.
 >
 >  
 >
 >>In fact it means that any thread doing blocking stdio is uncancellable -
 >>the standard may not require it but many applications might expect it.
 >>Given that the functionality was there in 4.x and lost in 5.x I'd call
 >>it a regression.
 >>    
 >>
 >
 >fgets() was not supposed to be cancellable in 4.x.  If it
 >is, it is not by intention.  Anything that calls _foo (single
 >underscore versions of system calls) is intentionally doing
 >it that way to avoid entering undesired cancellation points
 >(and blocking points in the case of libc_r).  There are other
 >uses of _read() within libc and those may not want to be
 >cancellation points.
 >
 >The overall design of libc is that all internal uses of system
 >calls use the single underscore versions and let the threads
 >library override them if it wants.  _foo() is not supposed to
 >be cancellable, and, in the case of libc_r, is also not supposed
 >to allow the process to block when hit (libc_r converts _read()
 >and _write() to poll(), then switches to another thread).  I
 >don't know why fgets() ends up as a cancellation point in libc_r,
 >but it shouldn't be by design -- it is a bug.
 >
 >  
 >
 
 --------------080409080603080600050704
 Content-Type: text/html; charset=us-ascii
 Content-Transfer-Encoding: 7bit
 
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 <html>
 <head>
   <meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">
   <title></title>
 </head>
 <body text="#000000" bgcolor="#ffffff">
 Uncle.&nbsp; Okay - you're right, sigh.<br>
 <br>
 It's not so much that we're using fgets() as many/most C based parsing
 libraries use stdio, bleh.<br>
 <br>
 As for why libc_r is cancellable...<br>
 <br>
 In 4.x&nbsp; _foo() sets the cancellation state and calls __foo() (for read,
 write, et.al), in 5.3 it's reversed.&nbsp; <br>
 --<br>
 Mark<br>
 <br>
 <blockquote type="cite"
  cite="midPine.GSO.4.43.0410071721330.1700-100000 at sea.ntplx.net">
   <pre wrap="">On Thu, 7 Oct 2004, Mark Gooderum wrote:
 
   </pre>
   <blockquote type="cite">
     <pre wrap="">But this is a major change in behavior from FreeBSD 4 and also a
 difference from Linux.  I'm not a Linux bigot at all but there is a
 recurring theme that XX threaded apps works on Linux but is unstable on
 FreeBSD and these sort of major behavior deltas contribute to the
 perception of FreeBSD threading as unstable by some.
     </pre>
   </blockquote>
   <pre wrap=""><!---->
 If you want to be portable, you should be using select() or
 poll().  It's not like there is no portable way of doing
 what you want, and in fact relying on fgets() to be cancellable
 is not portable.
 
   </pre>
   <blockquote type="cite">
     <pre wrap="">In fact it means that any thread doing blocking stdio is uncancellable -
 the standard may not require it but many applications might expect it.
 Given that the functionality was there in 4.x and lost in 5.x I'd call
 it a regression.
     </pre>
   </blockquote>
   <pre wrap=""><!---->
 fgets() was not supposed to be cancellable in 4.x.  If it
 is, it is not by intention.  Anything that calls _foo (single
 underscore versions of system calls) is intentionally doing
 it that way to avoid entering undesired cancellation points
 (and blocking points in the case of libc_r).  There are other
 uses of _read() within libc and those may not want to be
 cancellation points.
 
 The overall design of libc is that all internal uses of system
 calls use the single underscore versions and let the threads
 library override them if it wants.  _foo() is not supposed to
 be cancellable, and, in the case of libc_r, is also not supposed
 to allow the process to block when hit (libc_r converts _read()
 and _write() to poll(), then switches to another thread).  I
 don't know why fgets() ends up as a cancellation point in libc_r,
 but it shouldn't be by design -- it is a bug.
 
   </pre>
 </blockquote>
 </body>
 </html>
 
 --------------080409080603080600050704--
 


More information about the freebsd-threads mailing list