|
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+3/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+3/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+3/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+3/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