tags:

views:

130

answers:

2

Why does the following method hang?

public void pipe(Reader in, Writer out) {
    CharBuffer buf = CharBuffer.allocate(DEFAULT_BUFFER_SIZE);
    while( in.read(buf) >= 0 ) {
      out.append(buf.flip());
    }
}
+1  A: 

Answering my own question: you have to call buf.clear() between reads. Presumably, read is hanging because the buffer is full. The correct code is

public void pipe(Reader in, Writer out) {
    CharBuffer buf = CharBuffer.allocate(DEFAULT_BUFFER_SIZE);
    while( in.read(buf) >= 0 ) {
      out.append(buf.flip());
      buf.clear();
    }
}
Chris Conway
Hanging? Looking at the Readable API, I'd expect it to busy loop returning 0 on each read if the buffer is full, but that's a guess since it doesn't explicitly say what 'attempts to read' means. Hanging might mean that because you're multiply-writing the output, you've blocked the output.
Steve Jessop
I didn't check the detailed behavior of the loop. Either read blocks or repeatedly returns 0. The net effect: the loop never terminates.
Chris Conway
I guess for blocking to happen the output stream must be something with a finite capacity that isn't being drained, like a circular buffer - pretty rare case. Maybe I'm idiosyncratic in that I generally use "hang" to mean a deadlock rather than a livelock.
Steve Jessop
A: 

I would assume that it is a deadlock. The in.read(buf) locks the CharBuffer and prevents the out.append(buf) call.

That is assuming that CharBuffer uses locks (of some kind)in the implementation. What does the API say about the class CharBuffer?

Edit: Sorry, some kind of short circuit in my brain... I confused it with something else.

Tobias Wärre