+ // Android's java.nio implementation has a big lock inside the selector, preventing any concurrent access to it.
+ // This appears to largely defeat the entire purpose of java.nio, but we work around it here by explicitly checking
+ // for an Android environment and passing any selector access on any thread other than our internal one through
+ // do_selector_action, which wakes up the selector before accessing it.
+ private static boolean IS_ANDROID;
+ static {
+ IS_ANDROID = System.getProperty("java.vendor").toLowerCase().contains("android");
+ }
+ private boolean wakeup_selector = false;
+ private interface SelectorCall {
+ void meth() throws IOException;
+ }
+ private void do_selector_action(SelectorCall meth) throws IOException {
+ if (IS_ANDROID) {
+ wakeup_selector = true;
+ this.selector.wakeup();
+ synchronized (this.selector) {
+ meth.meth();
+ wakeup_selector = false;
+ }
+ } else {
+ meth.meth();
+ }
+ }
+
+ static private Field CommonBasePointer;
+ static {
+ try {
+ Class c = PeerManager.class.getSuperclass();
+ CommonBasePointer = c.getDeclaredField("ptr");
+ CommonBasePointer.setAccessible(true);
+ long _dummy_check = CommonBasePointer.getLong(Ping.of((short)0, (short)0));
+ } catch (NoSuchFieldException | IllegalAccessException e) {
+ throw new IllegalArgumentException(
+ "We currently use reflection to access protected fields as Java has no reasonable access controls", e);
+ }
+ }
+