1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.util.internal;
17
18 import io.netty.util.internal.logging.InternalLogger;
19 import io.netty.util.internal.logging.InternalLoggerFactory;
20
21 import java.lang.reflect.InvocationTargetException;
22 import java.lang.reflect.Method;
23 import java.nio.ByteBuffer;
24
25
26
27
28 final class CleanerJava9 implements Cleaner {
29 private static final InternalLogger logger = InternalLoggerFactory.getInstance(CleanerJava9.class);
30
31 private static final Method INVOKE_CLEANER;
32
33 static {
34 final Method method;
35 final Throwable error;
36 if (PlatformDependent0.hasUnsafe()) {
37 ByteBuffer buffer = ByteBuffer.allocateDirect(1);
38 Object maybeInvokeMethod;
39 try {
40
41 Method m = PlatformDependent0.UNSAFE.getClass().getDeclaredMethod("invokeCleaner", ByteBuffer.class);
42 m.invoke(PlatformDependent0.UNSAFE, buffer);
43 maybeInvokeMethod = m;
44 } catch (NoSuchMethodException e) {
45 maybeInvokeMethod = e;
46 } catch (InvocationTargetException e) {
47 maybeInvokeMethod = e;
48 } catch (IllegalAccessException e) {
49 maybeInvokeMethod = e;
50 }
51 if (maybeInvokeMethod instanceof Throwable) {
52 method = null;
53 error = (Throwable) maybeInvokeMethod;
54 } else {
55 method = (Method) maybeInvokeMethod;
56 error = null;
57 }
58 } else {
59 method = null;
60 error = new UnsupportedOperationException("sun.misc.Unsafe unavailable");
61 }
62 if (error == null) {
63 logger.debug("java.nio.ByteBuffer.cleaner(): available");
64 } else {
65 logger.debug("java.nio.ByteBuffer.cleaner(): unavailable", error);
66 }
67 INVOKE_CLEANER = method;
68 }
69
70 static boolean isSupported() {
71 return INVOKE_CLEANER != null;
72 }
73
74 @Override
75 public void freeDirectBuffer(ByteBuffer buffer) {
76 try {
77 INVOKE_CLEANER.invoke(PlatformDependent0.UNSAFE, buffer);
78 } catch (Throwable cause) {
79 PlatformDependent0.throwException(cause);
80 }
81 }
82 }