Bug 691278

Summary: select should return when pipe still has readable data
Product: [Fedora] Fedora Reporter: Tim Taiwanese Liim <tim.liim>
Component: perlAssignee: Marcela Mašláňová <mmaslano>
Status: CLOSED NOTABUG QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 14CC: cweyl, iarnell, kasal, lkundrak, mmaslano, ppisar, psabata, rc040203, tcallawa
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2011-03-28 04:49:26 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Attachments:
Description Flags
the producer.pl code
none
the consumer.pl code none

Description Tim Taiwanese Liim 2011-03-28 04:01:57 UTC
Description of problem:
    select() should return when a fd is readable.  In the attached
    producer-consumer pair, select() did not return when the pipe
    still has readable data in it.

    I am guessing this issue is not really perl specific, but related
    to kernel or libc.  But since I found it in perl first, I am
    reporting it here.  Please assign it to other module as you judge
    appropriate.  If the example perl script is wrong, please correct
    me and close this bug.

    What does the example producer-consumer pair do?
    - producer.pl ("P") prints two lines every 5 sec, with auto flush on.
    - consumer.pl ("C") spawns producer.pl with open(F, "producer.pl|"),
      and read from the pipe.

    - without arguments (so C just does "while (<F>) ..."), C prints
      the two lines from P just fine, every 5 sec.  For example,
      C got the line with "1 b" at the same second when P produces it.
            Sun Mar 27 23:37:24 2011: Sun Mar 27 23:37:24 2011 1 a
            Sun Mar 27 23:37:24 2011: Sun Mar 27 23:37:24 2011 1 b
            ^^^^^^ timestamp from C   ^^^^^^ timestamp from P

    - with "s" as arg, C uses select() to determine if data is
      available.  If so, reads and prints it.  BUT C reads the line "1
      b" 5 seconds later than P produces it:
            Sun Mar 27 23:36:48 2011: Sun Mar 27 23:36:48 2011 1 a
            Sun Mar 27 23:36:53 2011: Sun Mar 27 23:36:48 2011 1 b
                             ^^                        ^^
      P produces "1 b" at 23:36:48, but C reads it 5 sec later at
      23:36:53.


Version-Release number of selected component (if applicable):
    perl-5.12.3-141.fc14.x86_64

How reproducible:
    always

Steps to Reproduce:
    1. download attached consumer.pl, producer.pl
    2. run "consumer.pl"   for 30 sec, then ctrl-C to interrupt.
    3. run "consumer.pl s" for 30 sec, then ctrl-C to interrupt.

Actual results:
    At step 2, C (with "while (<F>) ...") reads from P as soon as P 
    flushes stdout (good):
            Sun Mar 27 23:58:37 2011: Sun Mar 27 23:58:37 2011 1 a
            Sun Mar 27 23:58:37 2011: Sun Mar 27 23:58:37 2011 1 b
            Sun Mar 27 23:58:42 2011: Sun Mar 27 23:58:42 2011 2 a
            Sun Mar 27 23:58:42 2011: Sun Mar 27 23:58:42 2011 2 b

    At step 3, C (with select() does not read data from P until next
    set of data from P arrives (bad):
            Sun Mar 27 23:58:57 2011: Sun Mar 27 23:58:57 2011 1 a
            Sun Mar 27 23:59:02 2011: Sun Mar 27 23:58:57 2011 1 b
            Sun Mar 27 23:59:02 2011: Sun Mar 27 23:59:02 2011 2 a
            Sun Mar 27 23:59:07 2011: Sun Mar 27 23:59:02 2011 2 b
    because select() does not return even when pipe from P has
    readable data in it.

Expected results:
    select() should return as long as there is readable data in fd,
    so step 3 should behaves just like step 2.

Additional info:
    n/a

Comment 1 Tim Taiwanese Liim 2011-03-28 04:03:00 UTC
Created attachment 488070 [details]
the producer.pl code

Comment 2 Tim Taiwanese Liim 2011-03-28 04:03:40 UTC
Created attachment 488071 [details]
the consumer.pl code

Comment 3 Tim Taiwanese Liim 2011-03-28 04:49:26 UTC
I see what I missed. select() and "$_ = <F>" does not go well
together; <F> reads all available data into its own buffer, thus
select() sees no more readable fd.

Will close this bug now.