 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
lhyatt@princeton.edu Guest
|
Posted: Thu Feb 09, 2006 11:06 am Post subject: Unexpected blocking and streambuf::in_avail() |
|
|
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
|
Posted: Thu Feb 09, 2006 3:06 pm Post subject: Re: Unexpected blocking and streambuf::in_avail() |
|
|
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
|
Posted: Thu Feb 09, 2006 6:06 pm Post subject: Re: Unexpected blocking and streambuf::in_avail() |
|
|
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
|
Posted: Fri Feb 10, 2006 3:06 am Post subject: Re: Unexpected blocking and streambuf::in_avail() |
|
|
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 |
|
 |
|
|
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
|
|