Sitelet https://web.archive.org/web/20201023082330/https://github.com/dnsjava/dnsjava/pull/96
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only select for tcp write when there is something to write #96

Closed
wants to merge 2 commits into from

Conversation

@rouzwawi
Copy link

@rouzwawi rouzwawi commented Mar 16, 2020

Avoids putting the selector loop in full spin by removing the OP_WRITE selection key when there's nothing to write. I also removed the registrationQueue from the tcp client since we can just call connect immediately as we create the socket, and register the OP_CONNECT key there.


fixes #95

fixes #95
@rouzwawi
Copy link
Author

@rouzwawi rouzwawi commented Mar 16, 2020

@ibauersachs
Copy link
Member

@ibauersachs ibauersachs commented Mar 17, 2020

Thanks for the investigation! I'll try to look at this asap. I assume with this changes your scenario is now working correctly?

@@ -265,8 +248,10 @@ private void processWrite() {
c.bind(local);
}

final ChannelState channelState = new ChannelState(c);
c.register(selector, SelectionKey.OP_CONNECT, channelState);

This comment has been minimized.

@ibauersachs

ibauersachs Mar 17, 2020
Member

AFAIR this won't work in a multithreaded scenario. A registration on the selector must be made on the selector thread or it can cause deadlocks.

This comment has been minimized.

@rouzwawi

rouzwawi Mar 17, 2020
Author

I guess you're referring to this in the Selector docs:

A selector's key and selected-key sets are not, in general, safe for use by multiple concurrent threads. If such a thread might modify one of these sets directly then access should be controlled by synchronizing on the set itself. The iterators returned by these sets' iterator methods are fail-fast: If the set is modified after the iterator is created, in any way except by invoking the iterator's own remove method, then a ConcurrentModificationException will be thrown.

Since SelectableChannel.register modifies the selectors key set, it might cause that ConcurrentModificationException to be thrown. But in general it seems that the register method itself can be called from multiple threads.

Anyhow, I think I will revert back to using the registration queue to avoid having to deal with concurrent modification exceptions on the selector thread.

This comment has been minimized.

@ibauersachs

ibauersachs Mar 17, 2020
Member

It's been a while, but I think I actually ran into deadlocks (not the ConcurrentModificationException) when registering from outside the selector thread.

This comment has been minimized.

@rouzwawi
Copy link
Author

@rouzwawi rouzwawi commented Mar 18, 2020

Any ETA on when this can be merged/released?

@rouzwawi
Copy link
Author

@rouzwawi rouzwawi commented Mar 18, 2020

I assume with this changes your scenario is now working correctly?

Yes I’ve tested a local snapshot build with a service and i don’t see the timeouts (and 100% cpu core usage).

@ibauersachs ibauersachs changed the base branch from master to 3.0.x Mar 19, 2020
@ibauersachs ibauersachs changed the base branch from 3.0.x to master Mar 19, 2020
@ibauersachs
Copy link
Member

@ibauersachs ibauersachs commented Mar 19, 2020

Any ETA on when this can be merged/released?

Done. It might take a while until it has propagated through Central.

@rouzwawi rouzwawi deleted the rouzwawi:tcp-states branch Mar 19, 2020
@rouzwawi
Copy link
Author

@rouzwawi rouzwawi commented Mar 19, 2020

Great thanks!

@ibauersachs ibauersachs added this to the v3.0.2 milestone May 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

2 participants
You can’t perform that action at this time.