C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Unexpected blocking and streambuf::in_avail()

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
lhyatt@princeton.edu
Guest





PostPosted: Thu Feb 09, 2006 11:06 am    Post subject: Unexpected blocking and streambuf::in_avail() Reply with quote



Hello-

I am having some strange difficulties getting interprocess
communication to work. (The details are probably off topic here but its
related to using named pipes on Linux). The short question is, if
streambuf::in_avail() returns nonzero, is that supposed to guarantee
that a call to get() will return immediately?

I have code along these lines:

ifstream f(filename);
char c;
if(f.rdbuf()->in_avail()>0) f.get(c);

I would expect this to either do nothing or fill c immediately, which
is the case on most systems, but on particular compilers the call to
get() will block until the process writing to the FIFO terminates, in
which case all the output it sent becomes available at once. (Even
though the output process was sending unbuffered output).

Curiously, if I do this:

char buffer;
f.rdbuf()->pubsetbuf(&buffer,1);

before the read, then everything works as expected. (It doesn't work if
I set the buffer size to 0 though, even though it is supposed to).

Anyway, sorry if this was too much OS-specific information, but the
bottom line question is, according to the standard, does in_avail() > 0
imply that get() should return immediately?

Thanks to anyone who has any advice.

-Lewis


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Carl Barron
Guest





PostPosted: Thu Feb 09, 2006 3:06 pm    Post subject: Re: Unexpected blocking and streambuf::in_avail() Reply with quote



In article <1139439823.436995.77410 (AT) g47g2000cwa (DOT) googlegroups.com>,
<"lhyatt (AT) princeton (DOT) edu"> wrote:

Quote:
Hello-

I am having some strange difficulties getting interprocess
communication to work. (The details are probably off topic here but its
related to using named pipes on Linux). The short question is, if
streambuf::in_avail() returns nonzero, is that supposed to guarantee
that a call to get() will return immediately?

I have code along these lines:

ifstream f(filename);
char c;
if(f.rdbuf()->in_avail()>0) f.get(c);

I would expect this to either do nothing or fill c immediately, which
is the case on most systems, but on particular compilers the call to
get() will block until the process writing to the FIFO terminates, in
which case all the output it sent becomes available at once. (Even
though the output process was sending unbuffered output).

Curiously, if I do this:

char buffer;
f.rdbuf()->pubsetbuf(&buffer,1);

before the read, then everything works as expected. (It doesn't work if
I set the buffer size to 0 though, even though it is supposed to).

Anyway, sorry if this was too much OS-specific information, but the
bottom line question is, according to the standard, does in_avail() > 0
imply that get() should return immediately?

Thanks to anyone who has any advice.

-Lewis

in_avail() should see if there is any data in the stream buffer's

buffer and if any return the # characters therein. If not it calls
showmanyc().
All input from your device in a buffered streambuf is done in
underflow(). In_available() does

if there is a buffer
if the # of unread chars in the buffer > 0 return this number.
else
return showmanyc()

showmanyc() is a virtual protected function that defaults to return
0. [supposed to use a device dependent estimate of the # of chars to
read without blocking]

If you are interested see Langer and Kreft's book on the iostream
library [includes streambuf] and locales. It is worth reading by
anyone with more than a passing interests of what the IO stream and/or
locale libraries provide. Sorry I don't have it handy to quote title
or isbn...

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
lhyatt@princeton.edu
Guest





PostPosted: Thu Feb 09, 2006 6:06 pm    Post subject: Re: Unexpected blocking and streambuf::in_avail() Reply with quote



OK, thanks for the reply. I gather from what you've said that if
in_avail() returns nonzero, but input blocks anyway, it must be the
case that the nonzero value is coming from showmanyc()... so it appears
that showmanyc() on this particular platform is not reliable. It still
doesn't explain why the input from a named pipe blocks when read with
iostreams, but not with cstdio, though, although I suppose that is a
UNIX question.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Alberto Ganesh Barbati
Guest





PostPosted: Fri Feb 10, 2006 3:06 am    Post subject: Re: Unexpected blocking and streambuf::in_avail() Reply with quote

Carl Barron ha scritto:
Quote:
All input from your device in a buffered streambuf is done in
underflow(). In_available() does

if there is a buffer
if the # of unread chars in the buffer > 0 return this number.
else
return showmanyc()

showmanyc() is a virtual protected function that defaults to return
0. [supposed to use a device dependent estimate of the # of chars to
read without blocking]

Your interpretation of showmanyc() is not correct. showmanyc() returns
"an estimate of the number of characters available in the sequence, or
-1. If it returns a positive value, then successive calls to underflow()
will not return traits::eof() until at least that number of characters
have been extracted from the stream."

So if the buffer is empty and in_avail() == showmanyc() returns a
positive number, get() will eventually call underflow(), which is
potentially blocking, in order to extract the next character.

I'm afraid but AFAIK there's no way to do a non-blocking get or peek
that relies only on the public interface of basic_streambuf. That's
really a pity, indeed.

HTH,

Ganesh

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.