NIO - Selector.select() doesn't block

D

Domagoj Klepac

Anyone worked with NIO (Java 1.5)?

I cannot seem to figure this one - the example from the web works as
expected, but my code doesn't, and I can't find the part which makes
the difference.

My selector.select() or selector.select(timeout) work as expected
until the connection is established. After that, they return 0
immediately. That results in 100% processor usage during the
connection. After the connection(s) is/are closed, select() blocks
again as expected.

Except for 100% processor usage, my program works fine - bytes get
read and written correctly.

Now, I've googled and googled and I've found several possible causes
which don't seem to apply:
- it's not a bug in NIO - all such bugs seem to be fixed by 1.5
- I'm removing the key from the ready set after processing via
iterator.remove()
- I'm not interrupting select with selector.wakeup() (at least not
until shutdown)
- my channels are not blocking, and I'm registering channels with
selector from the same thread that calls selector.select().

From what I know, selector.select() should return 0 only when
interrupted by selector.wakeup(). Selector.select(timeout) should
return 0 only if interrupted by selector.wakeup() or after the timeout
expires.

Are there any other cases where selector.select() returns immediately?

Domchi
 
S

Stefan Schulz

Make sure you clear() the selected set once you are done with it. If
there are still keys in that set, select() will return immediatly with
those keys.
 
D

Domagoj Klepac

Make sure you clear() the selected set once you are done with it. If
there are still keys in that set, select() will return immediatly with
those keys.

Shouldn't in that case select() return value greater than 0?

In any case, I've just tried explicitly clearing the set, and the
problem persists. :(

Domchi
 
S

Stefan Schulz

Domagoj said:
Shouldn't in that case select() return value greater than 0?

In any case, I've just tried explicitly clearing the set, and the
problem persists. :(

Hmm, can you provide us with an self-contained example that exhibits
the problem?
 
D

Domagoj Klepac

Hmm, can you provide us with an self-contained example that exhibits
the problem?

Hmph.

I found the problem while I was making the simplified example for
posting. I was registering for OP_CONNECT after the connection was
already established. Though I'm not quite sure why that breaks the
selector. I would expect either some kind of exception or acceptable
key in the ready set (in that case select() should return 1 instead
0).

Domchi
 
R

Remon van Vliet

Domagoj Klepac said:
Anyone worked with NIO (Java 1.5)?

I cannot seem to figure this one - the example from the web works as
expected, but my code doesn't, and I can't find the part which makes
the difference.

My selector.select() or selector.select(timeout) work as expected
until the connection is established. After that, they return 0
immediately. That results in 100% processor usage during the
connection. After the connection(s) is/are closed, select() blocks
again as expected.

Except for 100% processor usage, my program works fine - bytes get
read and written correctly.

Now, I've googled and googled and I've found several possible causes
which don't seem to apply:
- it's not a bug in NIO - all such bugs seem to be fixed by 1.5
- I'm removing the key from the ready set after processing via
iterator.remove()
- I'm not interrupting select with selector.wakeup() (at least not
until shutdown)
- my channels are not blocking, and I'm registering channels with
selector from the same thread that calls selector.select().

From what I know, selector.select() should return 0 only when
interrupted by selector.wakeup(). Selector.select(timeout) should
return 0 only if interrupted by selector.wakeup() or after the timeout
expires.

Are there any other cases where selector.select() returns immediately?

Domchi

Which operations do you have registered? If you register OP_WRITE the
behaviour you describe is correct because the OP_WRITE is (almost) always
ready, and thus select() always returns immediately, removing the key from
the selectedKeys() collection is not related to your problem. Please post
your registration code and your select loop if the problem is not fixed by
removing the OP_WRITE registration.

On that note, OP_WRITE should only be added to the interested ops set if you
are sure you actually have something to write.

Regards,

- Remon
 
R

Remon van Vliet

Remon van Vliet said:
Which operations do you have registered? If you register OP_WRITE the
behaviour you describe is correct because the OP_WRITE is (almost) always
ready, and thus select() always returns immediately, removing the key from
the selectedKeys() collection is not related to your problem. Please post
your registration code and your select loop if the problem is not fixed by
removing the OP_WRITE registration.

On that note, OP_WRITE should only be added to the interested ops set if
you are sure you actually have something to write.

Regards,

- Remon

never mind, i missed the post where you found the issue ;)
 
G

Gordon Beaton

On that note, OP_WRITE should only be added to the interested ops
set if you are sure you actually have something to write.

And not even then, in most cases, since the socket is almost always
writeable without blocking anyway. It's only necessary to register
OP_WRITE after a previous write operation has failed (written 0 or
short), and then only until the write succeeds.

/gordon
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top