develooper Front page | perl.perl5.porters | Postings from February 2004

Re: [perl #26787] read reports wrong eof under high system load

Thread Previous | Thread Next
From:
perl5-porters
Date:
February 19, 2004 06:37
Subject:
Re: [perl #26787] read reports wrong eof under high system load
Message ID:
c12hgr$bcl$1@post.home.lunix
In article <40346D81.8090905@cms.hu-berlin.de>,
	Michael Bell <michael.bell@cms.hu-berlin.de> writes:
> (Ton Hospel) via RT wrote:
>> In article <rt-3.0.8-26787-78336.2.2498005290219@perl.org>,
>> 	Michael Bell (via RT) <perlbug-followup@perl.org> writes:
>>
>>>If a Linux system runs with a high system load then it can happen
>>>that "read" returns a 0 but it is no EOF. The perldocumentation
>>>"man perlfunc" includes the statement that a zero only happens at
>>>EOF. We tested the same situation with a Solaris system which
>>>does not produce this error.
>>>
>>
>> Personally I'd rather see this reported as a linux bug. Do
>> you have code to reproduce this ?
>
> No, I have no small script to do this. We found this problem during
> testing a batch system for a PKI (OpenCA). The problem only happens if
> you have more than 90 percent total system load.
>
> I don't think that it is a Linux bug because this behaviour is compliant
> to the POSIX specs. I think that Perl is not aware of the latest POSIX
> specs (blocking read can return zero characters and this is correct).
> BTW I think that the real bug is in the POSIX specs because there is not
> explicitly written that a zero always signals EOF if it is a blocking
> read on a regular file. I like the Solaris behaviour much more than the
> Linux one's.

My reading only mentions a rather obscure "If any portion of a regular
file prior to the end-of-file has not been written, read() returns bytes
with value 0."

Apart form that this seems appropiate:
"If O_NONBLOCK is clear, read() will block the calling thread until
some data becomes available"
and
"If the starting position is at or after the end-of-file, 0 will be returned."

But anyways, I don't think perl CAN work around this, since it cannot
just retry the read. How often should you retry ? And you could still be
unlucky. Nor would the semantics be right since perl doesn't KNOW what
kind of fildescriptor is really behind the thing being read. You don't
want to do multiple reads from e.g. a tty where the user expects ^D to
"close" it instead of the read just being restarted.

So even if it's allowed in POSIX (which I don't currently agree with),
it would be one of these (fortunately rare) places where POSIX fucked 
up, since there is no sane way to handle this situation. And the linux
people DO fix up such cases, so if you report this, I'm quite sure it
will be seen as a bug and fixed (see e.g. http://www.ussg.iu.edu/hypermail/linux/kernel/0207.2/0242.html and the discussion around that for the case that
close in principle may leave the filedescriptor open in case of an error
return, also leading to untenable semantics, and therefore fixed as a bug)
>
> My problem is that this beahviour means that there is no real blocking I
> /O. The only chance to find a EOF after a POSIX read is now
>
> pos = lseek (fildes, 0, SEEK_CUR);
> fstat (fildes, buf);
> if (pos >= buf.st_size) ...
>
> This only works for regular files. Again I think that a returned zero
> should signal EOF but the POSIX specs doesn't define this and the
> question is now is this wanted by the authors or not?
>
That's not even very dependable for regular files if they are still 
actively being written to and truncated.

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About