473,406 Members | 2,710 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

block on reading a half-filled buffer for ifstream

Hi all. I'm using ifstream to read from a named pipe but
i've encountered an annoying problem. For some reason, the
program blocks on reading an ifstream's internal buffer that's
only half-filled. Only when the buffer becomes full does
it resume execution.

Here's my test code for reading from a pipe:
//(compiled with g++ -std=c++98)
//---------------------------------------------
#include <iostream>
#include <fstream>
using namespace std;

const int BUFF_SIZE = 20;

int main()
{
char buffer[BUFF_SIZE+1];
std::ifstream fin("npipe");

std::streambuf * pbuf;
pbuf = fin.rdbuf();
pbuf->pubsetbuf(buffer,BUFF_SIZE);

char c[200];
while(1){

if(pbuf->in_avail() > 0) {
cout << "stuff in buffer: " << pbuf->in_avail() << endl;

fin >> c; //program blocks HERE if buffer not full

cout << "read in stuff : " << c << endl;
cout << "---------------------------" << endl;
}
else
usleep(500000);
}
fin.close();
}
//---------------------------------------------

And for writing to the pipe, i just use:

cat > npipe

on the terminal.

So when i type something down the pipe and hit the return key,
the program does immediately recognise that there's data
available (cos pbuf->in_avail() immediately becomes > 0).

But when i try to read in the data with >> operator, it blocks if
the data being sent does not completely fill up the buffer. So
in the above case, the program blocks until BUFF_SIZE chars have
been sent down the pipe.

incidentally, i tried other read functions in place of >>
but it yield the same result.

//fin.read(c,pbuf->in_avail()); //none of these work either
//fin.readsome(c, 1);
//char test= pbuf->sbumpc();
It is unlikely that it's a pipe problem because i've written
a separate program that uses the C's FILE pointer for reading
where I don't encounter this problem at all.

My question is: doesn't in_avail() specify the number of
characters that are collected and can be read from ifstream's buffer
without blocking? Is there any way i can read a
half-filled streambuf without it blocking on me? Or have i
misunderstood the concept of in_avail() + the readability of
a buffer here?

As a temporary make-do solution, i've set pubsetbuf(buffer,1);
so that whenever a char is received the buffer becomes full, which
kinda resembles an unbuffered stream. (and yes, i've tried
pubsetbuf(0,0) & it doesnt' work. see earlier post on this by
someone else.
http://groups.google.co.nz/groups?hl....de%26rnum%3D1
)

It would be nice if there's a way where i can set streambuf's
buffer size to something > 1 & still be able to read from
the half filled buffer without blocking.

Any suggestions? :)

Thanks heaps in advance,
Des
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 23 '05 #1
1 6215
in********@yahoo.com wrote:
std::ifstream fin("npipe");
std::streambuf * pbuf;
pbuf = fin.rdbuf(); while(1){
if(pbuf->in_avail() > 0) {
Whether this condition ever yields true is actually not
specified. Assuming that the file buffer implemetnation
merely does what the standard requires it returns the number
of characters in the input buffer, i.e. the number if knows
are present before blocking: this is what 'in_avail()' is
supposed to return. Since no character was read, no attempt
is made to read a character by 'in_avail()' since this could
block. If an implementation ever yields something different
from 'in_avail()' than '0' prior to the first read, you are
already relying on behavior which is not required by the
standard!
fin >> c; //program blocks HERE if buffer not full
If this block even though 'in_avail()' returned a value bigger
than zero, it has a very simple reason: the input of the
string only terminates when it detects a space character or
when it detect end of file. Whether there is a space in
currently available buffer or not is not told by 'in_avail()'.
.... and the end of the internal buffer does not count as EOF.
Thus, I'm actually a little puzzled why a buffer size of one
character should solve the problem. I would rather guess that
this assures that the newline on which "cat" sents its internal
buffer reaches the file buffer's buffer and allows the input
of string to terminate.

BTW, if you use the formatted input inserter for character
arrays you should setup a width for the stream to have a point
where input terminates prior to a buffer overrun: if you
receive a sequence of non-spaces which longer than the size of
your buffer, you get a buffer overrun. Probably, you should
better use input to a 'std::string' anyway: this does not have
this error prone feature. If you insist in using a character
array, use it like this:

std::size_t const size = 20;
char buf[size];
fin >> std::setw(size) >> buf;

It is safe to use the same size as the size of the buffer with
'std::setw()' because the stream will only read 'width() - 1'
characters and use the remaining character for a terminating
zero.
My question is: doesn't in_avail() specify the number of
characters that are collected and can be read from ifstream's buffer
without blocking?
No. It does something related: it specifies the number of
characters known to be available. It may return a smaller
number. The default implementation is to return the number of
characters in the stream buffer's buffer. If no character is
read, it is likely to return 0.
Is there any way i can read a half-filled streambuf without
it blocking on me?
Yes but it is not covered by the C++ standard: the standard has
no concept of non-blocking input. You would need to set your
stream to non-blocking using an environment specific approach,
e.g. fcntl(2), to allow non-blocking input. This might mean
that you need to create a simple file stream (it's easy: it is
just 10 lines of code) because you cannot assume that you can
fiddle with a file buffers file descriptor.
Or have i misunderstood the concept of in_avail() + the
readability of a buffer here?


I think you did. You also misunderstood how formatted input is
working.
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 23 '05 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Daniel Déchelotte | last post by:
Hi, This is actually two questions in one: how to have a block just fit the data it contains (see my "table-cell" kludge) and how to have it centered in a larger block? My idea is to have my...
20
by: ishmael4 | last post by:
hello everyone! i have a problem with reading from binary file. i was googling and searching, but i just cant understand, why isnt this code working. i could use any help. here's the source code:...
40
by: Kevin Yu | last post by:
is it a bad programming design to throw exception in the try block then catch it??
3
by: Alex Clark | last post by:
Hi All, I'm having some problems reading a network stream. I'm writing a lightweight POP client to handle a very specific task, but I keep unexpectedly reaching the end of the datastream when...
2
by: ruben | last post by:
Hi: After upgrading 7.4.2 to 7.4.5 quite smoothly in a Red Hat 8.0 box, we are having intermitent issues with certain online PHP transactions, returning this error: "Warning: pg_exec() query...
2
by: Jake Barnes | last post by:
Using javascript closures to create singletons to ensure the survival of a reference to an HTML block when removeChild() may remove the last reference to the block and thus destory the block is...
26
by: Bill Norton | last post by:
If you wrap one division around another like this: <div id="wrapper"> <div id="child">...</div> </div> ....the wrapper division will be considered the containing block of the child division...
10
by: Curious | last post by:
Hi, I've found that if I wrap my code with a try-catch block in the fashion illustrated below, it'll do what is specified in the catch section instead of crashing. Could anyone confirm that this...
2
by: cmdolcet69 | last post by:
How can i just parse out the Indicator Readings in a text file so that i can fill an arraylist with the indicator values -------------------Indicator Test RAW BIT Values-------------------...
8
by: Patrick | last post by:
Hello, I'm trying to align a text vertically in a link displayed as a block. But the text is always at top. Is there a solution? Your advices are welcome. Here is a test page: <html>
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.