Correct use of ReadableByteChannel

Discussion in 'Java' started by Harald Kirsch, Jun 28, 2004.

  1. For a piece of code intented to be rather
    generic, I thought it would be a good idea
    that it reads its input from a
    ReadableByteChannel. The main reason to
    choose it over an InputStream was that the
    channel can be obtained for an InputStream as
    well as for a RandomAccessFile.

    Now the question:

    How do you correctly perform a blocking read
    from a ReadableByteChannel given that it does
    not necessarily block?

    I came up with

    ReadableByteChannel source;
    ByteBuffer inBuf;
    ...
    int result;
    while( 0==(result=source.read(inBuf)) ) Thread.yield();

    In case the channel is blocking, the yield()
    will never be called. If the channel is
    non-blocking, the yield() may be called. But
    on a machine without much load, I am afraid
    it will generate load because no other thread
    is interested in the processor.

    Any ideas how this can be done better?

    Harald.
     
    Harald Kirsch, Jun 28, 2004
    #1
    1. Advertising

  2. Harald Kirsch

    iksrazal Guest

    (Harald Kirsch) wrote in message news:<>...
    > How do you correctly perform a blocking read
    > from a ReadableByteChannel given that it does
    > not necessarily block?
    >
    > I came up with
    >
    > ReadableByteChannel source;
    > ByteBuffer inBuf;
    > ...
    > int result;
    > while( 0==(result=source.read(inBuf)) ) Thread.yield();
    >
    > In case the channel is blocking, the yield()
    > will never be called. If the channel is
    > non-blocking, the yield() may be called. But
    > on a machine without much load, I am afraid
    > it will generate load because no other thread
    > is interested in the processor.
    >
    > Any ideas how this can be done better?
    >
    > Harald.


    I don't claim to have a lot of answers here, but I've been looking at
    this problem a lot recently. One of the options I'm exploring is using
    the emberio nio framework licensed under bsd. The code below does say
    its mostly helpful for non-blocking but seemingly that is because it
    keeps a read state for retrieval. So may be able to adapt this.
    Furthermore, a channel by default is blocking or can be made to ber
    blocking by giving a timeout. In any event, this is from emberio:

    /**
    * Reads data from the underlying channel into the internal
    ByteBufer here.
    * This attempts to fill up to the limit - and
    * returns true if it actually does go up to the limit. Returns
    false if it can't
    * read all the way up to limit characters. Either way, the read
    status is held here
    * internally so you can also query it later. This complete/not
    complete information
    * is most useful for non-blocking readers.
    */
    public boolean
    read () throws IOException
    {
    int numBytes = -1;

    // Think this little loop is odd? Well it is. The reason for it
    // is because TCP stacks have a tendency to activate with only 1
    byte
    // available, and a subsequent read immediately gets the rest of
    the data.
    // Very annoying, and this leads to us in the common sense
    scenario with
    // non-blocking to have to inject multiple READ events for no good
    reason.
    // This little loop tries the read again if it didn't complete the
    first
    // time around, and provides a noticable perf boost.
    //
    // The above of course applies for non-blocking I/O where we
    attempt a bit
    // more I/O than the socket would indicate. For blocking I/O we
    sit around
    // snarfing it all.
    for (int i = 0; ; i++)
    {
    if (endpoint.directWritesEnabled())
    {
    numBytes = channel.read (inBuffer);
    }
    else
    {
    synchronized (channel)
    {
    numBytes = channel.read (inBuffer);
    }
    }
    if (numBytes < 0)
    {
    endpoint.close (EIOReasonCode.DISCONNECTION);
    return (false);
    }
    else if (!inBuffer.hasRemaining())
    {
    return (true);
    }
    if (!endpoint.isBlocking() && i >= 2)
    {
    break;
    }
    }
    return (!inBuffer.hasRemaining());
    }

    Lastly, the o'reilly nio book has an example of using
    ReadableByteChannel with worker threads.

    If you come up with something you think works, could you post it?

    HTH

    Outsource to an American programmer living in brazil!
    http://www.braziloutsource.com/
    iksrazal
     
    iksrazal, Jun 28, 2004
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Tim Hubberstey
    Replies:
    0
    Views:
    1,094
    Tim Hubberstey
    Jul 3, 2003
  2. joon
    Replies:
    1
    Views:
    532
    Roedy Green
    Jul 8, 2003
  3. Dan

    correct or not correct?

    Dan, Oct 2, 2003, in forum: HTML
    Replies:
    7
    Views:
    465
  4. J.Ram
    Replies:
    7
    Views:
    679
  5. froil
    Replies:
    12
    Views:
    324
    Gunnar Hjalmarsson
    Mar 2, 2006
Loading...

Share This Page