Skip to content

Native channels on JRuby don't work with JDK builtin selectors #67

@headius

Description

@headius

There are a number of IO types in JRuby that don't come from the standard set of channels on the JDK. Primary example of this is UNIXSocket/Server, which are provided by jnr-unixsocket using jnr-enxio. jnr-enxio, because it uses FFI to perform all IO and selection operations, has its own provider and its own selectors.

In nio4r, selectors are always created using the default provider, so they will only work with channel types from that provider.

As a result, nio4r selectors do not work with JRuby's UNIXServer/Socket, and this is the root cause of jruby/jruby#2750.

The issue is further complicated by the use of IO.pipe channels to wake up the selector. IO.pipe channels in JRuby come from the default provider, and you can't use a single selector to handle channels from two different providers.

In JRuby, we mitigated this issue in our selector logic as follows:

  • If we're only selecting on one channel or multiple channels with the same provider, just get an appropriate selector for it from a pool. The pool is keyed off provider.
  • If we are selecting against channels from different providers, the enxio selection happens in a separate selector and thread with a pipe connecting it to the default provider and selector; this allows either selector to wake both.

It's not an ideal setup, but I think nio4r will need to duplicate this logic, or we need to expose the logic we have in JRuby more directly (i.e. not hidden behind IRubyObject wrangling).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions