|
26 | 26 |
|
27 | 27 | package com.oracle.svm.core.posix.attach;
|
28 | 28 |
|
29 |
| -import java.nio.charset.StandardCharsets; |
30 |
| - |
31 |
| -import jdk.graal.compiler.word.Word; |
32 |
| -import org.graalvm.nativeimage.StackValue; |
33 |
| -import org.graalvm.nativeimage.c.type.CCharPointer; |
34 |
| -import org.graalvm.nativeimage.c.type.CTypeConversion; |
35 | 29 | import org.graalvm.word.Pointer;
|
| 30 | +import org.graalvm.word.PointerBase; |
36 | 31 |
|
37 | 32 | import com.oracle.svm.core.attach.AttachListenerThread;
|
38 | 33 | import com.oracle.svm.core.posix.PosixUtils;
|
39 | 34 | import com.oracle.svm.core.posix.headers.Unistd;
|
40 | 35 | import com.oracle.svm.core.util.BasedOnJDKFile;
|
41 | 36 |
|
42 | 37 | public final class PosixAttachListenerThread extends AttachListenerThread {
|
43 |
| - @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/aix/attachListener_aix.cpp#L82") // |
44 |
| - private static final String PROTOCOL_VERSION = "1"; |
45 |
| - @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/aix/attachListener_aix.cpp#L269") // |
46 |
| - private static final int VERSION_SIZE = 8; |
47 |
| - @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/aix/attachListener_aix.cpp#L85") // |
48 |
| - private static final int ATTACH_ERROR_BAD_VERSION = 101; |
49 |
| - |
50 |
| - /** |
51 |
| - * Each attach request consists of a fixed number of zero-terminated UTF-8 strings. |
52 |
| - * {@code <version><commandName><arg0><arg1><arg2>} |
53 |
| - */ |
54 |
| - private static final int EXPECTED_STRING_COUNT = 2 + ARG_COUNT_MAX; |
55 |
| - private static final int MAX_REQUEST_LEN = (VERSION_SIZE + 1) + (NAME_LENGTH_MAX + 1) + (ARG_COUNT_MAX * (ARG_LENGTH_MAX + 1)); |
56 |
| - |
57 | 38 | private final int listener;
|
58 | 39 |
|
59 | 40 | public PosixAttachListenerThread(int listener) {
|
60 | 41 | this.listener = listener;
|
61 | 42 | }
|
62 | 43 |
|
63 | 44 | @Override
|
64 |
| - @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+3/src/hotspot/os/posix/attachListener_posix.cpp#L254-L311") |
65 |
| - protected PosixAttachOperation dequeue() { |
| 45 | + @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/posix/attachListener_posix.cpp#L256-L313") |
| 46 | + protected AttachOperation dequeue() { |
66 | 47 | while (true) {
|
67 | 48 | int socket = AttachHelper.waitForRequest(listener);
|
68 | 49 | if (socket == -1) {
|
69 | 50 | return null;
|
70 | 51 | }
|
71 | 52 |
|
72 |
| - PosixAttachOperation op = readRequest(socket); |
| 53 | + PosixAttachSocketChannel channel = new PosixAttachSocketChannel(socket); |
| 54 | + AttachOperation op = readRequest(channel); |
73 | 55 | if (op == null) {
|
74 |
| - /* Close the socket and try again. */ |
75 |
| - Unistd.NoTransitions.close(socket); |
| 56 | + channel.close(); |
76 | 57 | } else {
|
77 | 58 | return op;
|
78 | 59 | }
|
79 | 60 | }
|
80 | 61 | }
|
81 | 62 |
|
82 |
| - /** This method reads and processes a single request from the socket. */ |
83 |
| - @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/aix/attachListener_aix.cpp#L268-L359") |
84 |
| - private static PosixAttachOperation readRequest(int socket) { |
85 |
| - int strCount = 0; |
86 |
| - int[] stringEnds = new int[EXPECTED_STRING_COUNT]; |
87 |
| - Pointer buf = StackValue.get(MAX_REQUEST_LEN); |
88 |
| - |
89 |
| - /* Read until all expected strings have been read, the buffer is full, or EOF. */ |
90 |
| - int offset = 0; |
91 |
| - do { |
92 |
| - int n = PosixUtils.readUninterruptibly(socket, buf, MAX_REQUEST_LEN, offset); |
93 |
| - if (n == -1) { |
94 |
| - return null; |
95 |
| - } else if (n == 0) { |
96 |
| - break; |
97 |
| - } |
98 |
| - |
99 |
| - int end = offset + n; |
100 |
| - while (offset < end) { |
101 |
| - if (buf.readByte(offset) == 0) { |
102 |
| - /* End-of-string found. */ |
103 |
| - stringEnds[strCount] = offset; |
104 |
| - strCount++; |
105 |
| - } |
106 |
| - offset++; |
107 |
| - } |
108 |
| - } while (offset < MAX_REQUEST_LEN && strCount < EXPECTED_STRING_COUNT); |
109 |
| - |
110 |
| - if (strCount != EXPECTED_STRING_COUNT) { |
111 |
| - /* Incomplete or invalid request. */ |
112 |
| - return null; |
113 |
| - } |
114 |
| - |
115 |
| - String version = decodeString(buf, stringEnds, 0); |
116 |
| - if (!PROTOCOL_VERSION.equals(version)) { |
117 |
| - complete(socket, ATTACH_ERROR_BAD_VERSION, null); |
118 |
| - return null; |
119 |
| - } |
120 |
| - |
121 |
| - String name = decodeString(buf, stringEnds, 1); |
122 |
| - if (name.length() > NAME_LENGTH_MAX) { |
123 |
| - return null; |
124 |
| - } |
125 |
| - |
126 |
| - String arg0 = decodeString(buf, stringEnds, 2); |
127 |
| - if (arg0.length() > ARG_LENGTH_MAX) { |
128 |
| - return null; |
129 |
| - } |
| 63 | + @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/posix/attachListener_posix.cpp#L102-L139") |
| 64 | + private static class PosixAttachSocketChannel extends AttachSocketChannel { |
| 65 | + private int socket; |
130 | 66 |
|
131 |
| - String arg1 = decodeString(buf, stringEnds, 3); |
132 |
| - if (arg1.length() > ARG_LENGTH_MAX) { |
133 |
| - return null; |
| 67 | + PosixAttachSocketChannel(int socket) { |
| 68 | + this.socket = socket; |
134 | 69 | }
|
135 | 70 |
|
136 |
| - String arg2 = decodeString(buf, stringEnds, 4); |
137 |
| - if (arg2.length() > ARG_LENGTH_MAX) { |
138 |
| - return null; |
| 71 | + @Override |
| 72 | + public int read(PointerBase buffer, int size) { |
| 73 | + return PosixUtils.readUninterruptibly(socket, (Pointer) buffer, size, 0); |
139 | 74 | }
|
140 | 75 |
|
141 |
| - return new PosixAttachOperation(name, arg0, arg1, arg2, socket); |
142 |
| - } |
143 |
| - |
144 |
| - private static String decodeString(Pointer buf, int[] stringEnds, int index) { |
145 |
| - int start = index == 0 ? 0 : stringEnds[index - 1] + 1; |
146 |
| - int length = stringEnds[index] - start; |
147 |
| - assert length >= 0; |
148 |
| - return CTypeConversion.toJavaString((CCharPointer) buf.add(start), Word.unsigned(length), StandardCharsets.UTF_8); |
149 |
| - } |
150 |
| - |
151 |
| - @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+15/src/hotspot/os/posix/attachListener_posix.cpp#L323-L325") |
152 |
| - private static void complete(int socket, int code, String response) { |
153 |
| - /* Send the return code. */ |
154 |
| - byte[] returnCodeData = Integer.toString(code).getBytes(StandardCharsets.UTF_8); |
155 |
| - sendData(socket, returnCodeData); |
156 |
| - |
157 |
| - byte[] lineBreak = System.lineSeparator().getBytes(StandardCharsets.UTF_8); |
158 |
| - sendData(socket, lineBreak); |
159 |
| - |
160 |
| - /* Send the actual response message. */ |
161 |
| - if (response != null && !response.isEmpty()) { |
162 |
| - byte[] responseBytes = response.getBytes(StandardCharsets.UTF_8); |
163 |
| - sendData(socket, responseBytes); |
164 |
| - sendData(socket, lineBreak); |
| 76 | + @Override |
| 77 | + protected void write(byte[] data) { |
| 78 | + PosixUtils.writeUninterruptibly(socket, data); |
165 | 79 | }
|
166 | 80 |
|
167 |
| - AttachHelper.shutdownSocket(socket); |
168 |
| - Unistd.NoTransitions.close(socket); |
169 |
| - } |
170 |
| - |
171 |
| - private static void sendData(int socket, byte[] data) { |
172 |
| - PosixUtils.writeUninterruptibly(socket, data); |
173 |
| - } |
174 |
| - |
175 |
| - private static class PosixAttachOperation extends AttachOperation { |
176 |
| - private final int socket; |
177 |
| - |
178 |
| - PosixAttachOperation(String name, String arg0, String arg1, String arg2, int socket) { |
179 |
| - super(name, arg0, arg1, arg2); |
180 |
| - this.socket = socket; |
| 81 | + protected boolean isOpen() { |
| 82 | + return socket != -1; |
181 | 83 | }
|
182 | 84 |
|
183 | 85 | @Override
|
184 |
| - public void complete(int code, String response) { |
185 |
| - PosixAttachListenerThread.complete(socket, code, response); |
| 86 | + public void close() { |
| 87 | + if (isOpen()) { |
| 88 | + AttachHelper.shutdownSocket(socket); |
| 89 | + Unistd.NoTransitions.close(socket); |
| 90 | + socket = -1; |
| 91 | + } |
186 | 92 | }
|
187 | 93 | }
|
188 | 94 | }
|
0 commit comments