<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    On 16/01/2016 11:14, Richard Warburton wrote:<br>
    <blockquote type="cite"
cite="mid:CAMaYbvJXQUxhkMdUQvZQYp-axe5=j5j=ZRCyeCOFg_LeW_J6Fw@mail.gmail.com">
      <div dir="ltr">Hi gents,<br clear="all">
        <div><br>
        </div>
        <div>I've prototyped a callback based addition to the NIO
          Selector, which I've previously talked through a bit with Alan
          Bateman. The goal of the callback based selector is to avoid
          the current pattern of calling select/selectNow on a Nio
          selector and then having to iterate over a hashmap produced.
          This pattern being quite object allocation heavy for a
          critical path and also involving obtaining and releasing
          multiple locks. I'd like to propose that the following patch,
          which adds the ability to perform a select on a Selector that
          takes a callback handler.</div>
        <div><br>
        </div>
        <div><a
            href="http://cr.openjdk.java.net/%7Erwarburton/select-now-4/"
            rel="noreferrer" target="_blank" style="font-size:12px"
            moz-do-not-send="true">http://cr.openjdk.java.net/~rwarburton/select-now-4/</a></div>
        <div><br>
        </div>
        <div>I'm happy to iterate on the patch a bit based upon people's
          feedback and discuss any potential concerns or issues that you
          may have with the patch. Looking forward to hearing your
          feedback.</div>
        <br>
      </div>
    </blockquote>
    This one has been on my list for a long time to study more closely.
    When we discussed it here in 2016 I had concerns about invoking a
    consumer while synchronized on the selector and other locks. It has
    grown on my a bit so I spent a bit of time recently to work through
    the  implications, both spec and implementation.<br>
    <br>
    For the spec:  The Selector API describes selection operations in
    its class description and it's important to keep that consistent
    when introducing a new way to be notified of channels ready for I/O
    operations.<br>
    <br>
    The action is arbitrary code and we have to assume it will behave as
    if it's a bull in a china shop. It might attempt another selection
    operation on the same selector, it might close the selector, it
    might change the interest set or cancel a key for a channel
    registered with the selector but not yet seen by the consumer. All
    of these scenarios need consideration.<br>
    <br>
    Locking was mostly ignored in the original prototype but the locking
    has to be consistent with how the existing selection operations are
    specified. The main reason is processing the cancelled-key set means
    removing keys from the key set and selected-key set. On the surface,
    the new methods should not care about the selected-key set but they
    have to maintain the invariant that the selected-key set is always a
    subset of the selector's key set.<br>
    <br>
    Another point of detail is that the action may need to be called
    more than once for the same key but different ready sets. We have
    this with the kqueue implementation where events for read and write
    are registered with different filters. Other implementation might
    maintain separate poll arrays for read and write events.<br>
    <br>
    In terms of performance, the main benefit is that avoids adding keys
    to the selected-key set, only to be removed almost immediately by
    the code doing the select. This avoids garbage so helps the GC too.
    If we go ahead with these methods then it's important to get a good
    range of performance data and also see whether a specialized set to
    support the usage pattern of the selected-key set might be
    alternative to introducing new APIs.<br>
    <br>
    I've put a webrev here with candidate changes to the Selector API.
    It's one select(Consumer<SelectionKey>, timeout) for now, the
    select(Consumer<SelectionKey>) and
    selectNow(Consumer<SelectionKey>) variants are easy to add if
    needed. The webrev has a default implementation based on the
    existing API, and then implementations for macOS and Linux. Other
    platforms could be added later of course. I've also included a test
    that covers most of the scenarios.<br>
       <a class="moz-txt-link-freetext" href="http://cr.openjdk.java.net/~alanb/8199433/webrev/">http://cr.openjdk.java.net/~alanb/8199433/webrev/</a><br>
    <br>
    -Alan<br>
  </body>
</html>