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

Detect fake constants / platforms? #105

Open
ahorek opened this issue Oct 28, 2021 · 2 comments
Open

Detect fake constants / platforms? #105

ahorek opened this issue Oct 28, 2021 · 2 comments

Comments

@ahorek
Copy link
Contributor

ahorek commented Oct 28, 2021

moving the discussion from jruby/jruby#6843

we have a set of constants based on the platform we know
https://github.com/jnr/jnr-constants/blob/master/src/main/java/jnr/constants/platform/linux/AddressFamily.java
and some of them aren't defined

if we load them like this
https://github.com/jruby/jruby/blob/8f25a744ef7f24bbda63cdf00f72784192102d76/core/src/main/java/org/jruby/Ruby.java#L4597

require 'socket'
Socket.constants =>[AF_UNSPEC, AF_LOCAL, ....]

but for instance AF_IMPLINK won't be in the list on Linux

this is useful for feature checks like the one in Puma
https://github.com/puma/puma/blob/20dc923b0b83a829cc3e2578a2b2c0b854985c18/lib/puma/server.rb#L124

however, if there's a platform that isn't supported, we do load "fake constants"
https://github.com/jnr/jnr-constants/blob/master/src/main/java/jnr/constants/platform/fake/AddressFamily.java

in this case, suddenly Socket.constants will include all possible constants, so
Socket.const_defined?(:IPPROTO_TCP) will return true and the code that expects the feature to be supported breaks.

we're saying that we do support everything, but it's a false assumption.

I think it would be nice to be able to detect if these constants are real or not.
Note that fake constants aren't close to any platform and any code that depends on correct values for doing native calls will almost for sure break (mostly on unexpected and hard-to-track errors).
Of course, I can do a second platform check in JRuby to achieve the same goal, but it would be cleaner if jnr-constants could handle platform differences and give me the information about usability instead of trying to fake it.

this is just a topic for discussion based on the previous task I was working on. I have a workaround so feel free to close it :)

@headius
Copy link
Member

headius commented Oct 28, 2021

A bit more background here...

The "fake" constants were added early on, and I believe there were two primary reasons for them:

  • On platforms where we do not yet have generated constants, we could use the fake ones assuming they were "pretty close" to what the platform defines. In practice this turns out to be true only for a subset of constant values; many constants vary across platforms.
  • When running in a "pure-Java" mode that does not actually use native calls, we can use the set of fake constants as part of our native function emulation (in e.g. JRuby). This sets up the "fake platform" as though it were a real platform: the platform of no platform, or the platform of "pure Java".

I believe the latter is still a valid case, but the former is perhaps doing more harm than good. We also do not do a particularly good job of detecting that we are non-native and explicitly using the fake values; instead we always assume a given platform has values defined and may end up using fake values with real native functions.

@ahorek
Copy link
Contributor Author

ahorek commented Oct 28, 2021

thanks for sharing. The "pure-Java" mode makes sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants