By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,260 Members | 1,305 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,260 IT Pros & Developers. It's quick & easy.

I/O buffers

P: n/a
It was my understanding that doing something like
'cin.rdbuf()->pubsetbuf(NULL, 0)' would cause any buffering troubles to
stop. I am not sure where the problem resides, but I am experiencing
difficulties in this area.

Basically what I am trying to do is an interface/engine setup where the
engine communicates through stdin/out and the interface communicates
with the engine through pipes to these handles. I thought I had it
working correctly until I used a certain library (gnustep) to create an
interface and now I am running into what looks like a buffer issue.

When the interface sends two commands (separated by \n) to the engine
quickly the engine gets the first but then fails to read the second or
following. Later when the same set of commands is sent again the engine
recieves what it had not before and then the first of the current set.
I also tried something like 'cat | engine' and got similar results. Not
sure if cat is buffering or not. I am also unsure in which part the
problem resides, engine or interface.

I shut of cin's buffer with 'cin.rdbuf()->pubsetbuf(NULL,0)' and then
read lines with this code:

while (Interface::readReady())
{
cerr << "Input ready.\n";
string input = Interface::readLine();
if (!CommandDispatcher::interpretAndDispatch(input))
Interface::printRaw(string("Error (unknown command): ") + input
+ "\n");
}
readLine() is:
string final;

int c;
while (cin && (c = cin.get()) != '\n') // Read up to '\n'
final += c;

cerr << "Data Read: *" << final << "*" << endl;

return final;

Of course everything in Interface::readReady() is off-topic and
unfortunately this is what is failing. However, all this function does
is poll stdin (using select()) to see if something is available and
return true if so. I am wondering if the problem is actually elsewhere,
like the above snippets for instance.

Unfortunately I am also getting no responce for the readReady() function
from any on-topic group :P That is why I am really hoping that the
error is somewhere else.

NR

Jul 22 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
On Mon, 15 Dec 2003 20:30:10 -0800, Noah Roberts
<nr******@dontemailme.com> wrote:
It was my understanding that doing something like
'cin.rdbuf()->pubsetbuf(NULL, 0)' would cause any buffering troubles to
stop. I am not sure where the problem resides, but I am experiencing
difficulties in this area.
I think that buffering of stdin might be causing your problems, but it
isn't necessarily the case.
Basically what I am trying to do is an interface/engine setup where the
engine communicates through stdin/out and the interface communicates
with the engine through pipes to these handles. I thought I had it
working correctly until I used a certain library (gnustep) to create an
interface and now I am running into what looks like a buffer issue.
I've been there, done that, ended up rewriting to use shared memory
and native messaging for performance reasons, but don't let that stop
you (I was writing a realtime system). I did get it working before the
rewrite though, so read on...
When the interface sends two commands (separated by \n) to the engine
quickly the engine gets the first but then fails to read the second or
following. Later when the same set of commands is sent again the engine
recieves what it had not before and then the first of the current set.
I also tried something like 'cat | engine' and got similar results. Not
sure if cat is buffering or not. I am also unsure in which part the
problem resides, engine or interface.

I shut of cin's buffer with 'cin.rdbuf()->pubsetbuf(NULL,0)' and then
read lines with this code:
For a start, I'd remove the unbuffering call - the code can be fixed
so that you don't need it.

Have you set stdin to non-blocking? blocking is generally the default,
and might work best for you here (it simplifies the code a bit) if the
writer should be writing whole lines.
while (Interface::readReady())
{
cerr << "Input ready.\n";
string input = Interface::readLine();
if (!CommandDispatcher::interpretAndDispatch(input))
Interface::printRaw(string("Error (unknown command): ") + input
+ "\n");
}
readLine() is:
string final;

int c;
while (cin && (c = cin.get()) != '\n') // Read up to '\n'
final += c;
Replace the above with the briefer and faster:
std::getline(std::cin, final);
cerr << "Data Read: *" << final << "*" << endl;

return final;

Of course everything in Interface::readReady() is off-topic and
unfortunately this is what is failing. However, all this function does
is poll stdin (using select()) to see if something is available and
return true if so. I am wondering if the problem is actually elsewhere,
like the above snippets for instance.


readReady needs to be fixed by adding this to the start:

if (std::cin.in_avail() > 0)
return true;

If std::cin has any characters buffered, return immediately. Hopefully
that will fix your problem.

Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #2

P: n/a
readReady needs to be fixed by adding this to the start:

if (std::cin.in_avail() > 0)
return true;

If std::cin has any characters buffered, return immediately. Hopefully
that will fix your problem.


I will try that again, but last time I did it did not work as expected.
I don't recall which way it went, but in_avail returned the same value
no matter what conditions on certain systems.

Jul 22 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.