Switching from Non-Blocking to Blocking IO

C

Christian

Hello


I have just tried using non-Blocking IO in a JavaSE program.
My problem is that at one point I have to switch during the the running
protocol to blocking-io as some compressed data arrives and my gzip
implementation only allows decompressing from a blocking stream.


so what I tried was this

@Override
public ByteChannel retrieveChannel() throws IOException {

SocketChannel sc = (SocketChannel)key.channel();
key.cancel();

sc.configureBlocking(true);
sc.socket().setSoTimeout(20000);
return sc;
}

the problem with this code is that after calling retrieveChannel() some
data arrvies on the channel and is immediately read by the thread that
uses the selector to get all non-blocking io..

Now what have I done wrong?
It smells like a synchronization problem ..

Any hints for me? Or better solutions to the problem?

Christian
 
M

Mike Schilling

Christian said:
Hello


I have just tried using non-Blocking IO in a JavaSE program.
My problem is that at one point I have to switch during the the
running protocol to blocking-io as some compressed data arrives and
my gzip implementation only allows decompressing from a blocking
stream.


so what I tried was this

@Override
public ByteChannel retrieveChannel() throws IOException {

SocketChannel sc = (SocketChannel)key.channel();
key.cancel();

sc.configureBlocking(true);
sc.socket().setSoTimeout(20000);
return sc;
}

the problem with this code is that after calling retrieveChannel()
some data arrvies on the channel and is immediately read by the
thread that uses the selector to get all non-blocking io..

Now what have I done wrong?
It smells like a synchronization problem ..

Any hints for me? Or better solutions to the problem?


If you can buffer the entire gzip file in memory, do that, and point a
ByteArrayInputStream at the result. If not, create an InputStream subclass
that returns data from the socket and blocks when none is available. The
second is more complicated, of course, since it requires multiple threads
and some synchronization between them.
 
C

Christian

Mike said:
If you can buffer the entire gzip file in memory, do that, and point a
ByteArrayInputStream at the result. If not, create an InputStream subclass
that returns data from the socket and blocks when none is available. The
second is more complicated, of course, since it requires multiple threads
and some synchronization between them.

I can't buffer it in memory..
as size could be anything from 100KiB to 16 GiB
I was just hoping that switching would be possible to spare me the work
of implementing this workaround.
 
E

Esmond Pitt

Christian said:
It smells like a synchronization problem ..

Yup. Try waking up the selector immediately you deregister the channel.
Make sure the selector loop copes correctly with zero ready channels.
*Then* put the channel into blocking mode.
Any hints for me? Or better solutions to the problem?

On second thoughts, how did you get here in the first place? It must
have been in response to an OP_READ originally, which must have been
processed in the selector thread, so the deregister and switch to
blocking mode should have been done there, then you wouldn't have a problem.
 
C

Christian

Esmond said:
Yup. Try waking up the selector immediately you deregister the channel.
Make sure the selector loop copes correctly with zero ready channels.
*Then* put the channel into blocking mode.
My selector-thread sleeps for a few milliseconds when it is awakened and
no keys are selected. Is this the correct handling?
It works now but not allways.
Would it be better to submit a Runnable to the selector-thread to do
this unregistering and set to Blocking?
On second thoughts, how did you get here in the first place? It must
have been in response to an OP_READ originally, which must have been
processed in the selector thread, so the deregister and switch to
blocking mode should have been done there, then you wouldn't have a
problem.

IO thread reads protocol commands from the stream. Then an Executor is
used to handle this command. So the reading selector-thread doesn't know
the protocol and can therefore not do this.

Thank you for your help
Christian
 
E

Esmond Pitt

Christian said:
My selector-thread sleeps for a few milliseconds when it is awakened and
no keys are selected. Is this the correct handling?

Seems OK. As long as it sleeps longer than it takes the other thread to
get from wakeup() to cancel().
It works now but not allways.
Would it be better to submit a Runnable to the selector-thread to do
this unregistering and set to Blocking?

I've seen this technique used, sometimes quite extensively, but I've
never had to use it myself. It's always seemed like overkill to me, but
if it works for you ...
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top