Bug 691278 - select should return when pipe still has readable data
Summary: select should return when pipe still has readable data
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Fedora
Classification: Fedora
Component: perl
Version: 14
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Marcela Mašláňová
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2011-03-28 04:01 UTC by Tim Taiwanese Liim
Modified: 2011-03-28 04:49 UTC (History)
9 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2011-03-28 04:49:26 UTC
Type: ---


Attachments (Terms of Use)
the producer.pl code (148 bytes, text/plain)
2011-03-28 04:03 UTC, Tim Taiwanese Liim
no flags Details
the consumer.pl code (681 bytes, text/plain)
2011-03-28 04:03 UTC, Tim Taiwanese Liim
no flags Details

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.


Note You need to log in before you can comment on or make changes to this bug.