26
26
27
27
import java .util .function .Function ;
28
28
29
- import jdk .graal .compiler .word .Word ;
30
29
import org .graalvm .nativeimage .CurrentIsolate ;
31
30
import org .graalvm .nativeimage .Isolate ;
32
31
import org .graalvm .nativeimage .IsolateThread ;
41
40
import com .oracle .svm .core .c .function .CEntryPointOptions .NoPrologue ;
42
41
import com .oracle .svm .core .thread .VMThreads ;
43
42
43
+ import jdk .graal .compiler .word .Word ;
44
+
44
45
@ CHeader (value = GraalIsolateHeader .class )
45
46
public final class CEntryPointNativeFunctions {
46
47
@@ -158,12 +159,26 @@ public static int detachThread(IsolateThread thread) {
158
159
return CEntryPointActions .leaveDetachThread ();
159
160
}
160
161
162
+ static final String THREAD_TERMINATION_NOTE = """
163
+
164
+ If this call blocks indefinitely, this means there are still Java threads running
165
+ that do not terminate after receiving a Thread.interrupt() event. To prevent indefinite blocking,
166
+ these threads should be cooperatively terminated within Java before invoking this call.
167
+ To diagnose such issues, use the option '-R:TearDownWarningSeconds=<secs>' at image build time
168
+ to detect the threads that are still running. This will print the stack traces of all threads that block tear-down.
169
+ To resolve blocking issues, utilize any available method to terminate the offending threads. This may include
170
+ calling shutdown API functions, adjusting the application configuration, or leveraging reflection.
171
+ """ ;
172
+
161
173
@ Uninterruptible (reason = UNINTERRUPTIBLE_REASON )
162
- @ CEntryPoint (name = "tear_down_isolate" , documentation = {
163
- "Tears down the isolate of the passed (and still attached) isolate thread," ,
164
- "waiting for any attached threads to detach from it, then discards its objects," ,
165
- "threads, and any other state or context that is associated with it." ,
166
- "Returns 0 on success, or a non-zero value on failure." })
174
+ @ CEntryPoint (name = "tear_down_isolate" , documentation = {"""
175
+ Tears down the isolate of the passed (and still attached) isolate thread,
176
+ waiting for any attached threads to detach from it, then discards its objects,
177
+ threads, and any other state or context that is associated with it.
178
+ Returns 0 on success, or a non-zero value on failure.
179
+ """ ,
180
+ THREAD_TERMINATION_NOTE ,
181
+ })
167
182
@ CEntryPointOptions (prologue = NoPrologue .class , epilogue = NoEpilogue .class , nameTransformation = NameTransformation .class )
168
183
public static int tearDownIsolate (IsolateThread isolateThread ) {
169
184
int result = CEntryPointActions .enter (isolateThread );
@@ -174,17 +189,20 @@ public static int tearDownIsolate(IsolateThread isolateThread) {
174
189
}
175
190
176
191
@ Uninterruptible (reason = UNINTERRUPTIBLE_REASON )
177
- @ CEntryPoint (name = "detach_all_threads_and_tear_down_isolate" , documentation = {
178
- "In the isolate of the passed isolate thread, detach all those threads that were" ,
179
- "externally started (not within Java, which includes the \" main thread\" ) and were" ,
180
- "attached to the isolate afterwards. Afterwards, all threads that were started" ,
181
- "within Java undergo a regular shutdown process, followed by the tear-down of the" ,
182
- "entire isolate, which detaches the current thread and discards the objects," ,
183
- "threads, and any other state or context associated with the isolate." ,
184
- "None of the manually attached threads targeted by this function may be executing" ,
185
- "Java code at the time when this function is called or at any point in the future" ,
186
- "or this will cause entirely undefined (and likely fatal) behavior." ,
187
- "Returns 0 on success, or a non-zero value on (non-fatal) failure." })
192
+ @ CEntryPoint (name = "detach_all_threads_and_tear_down_isolate" , documentation = {"""
193
+ In the isolate of the passed isolate thread, detach all those threads that were
194
+ externally started (not within Java, which includes the "main thread") and were
195
+ attached to the isolate afterwards. Afterwards, all threads that were started
196
+ within Java undergo a regular shutdown process, followed by the tear-down of the
197
+ entire isolate, which detaches the current thread and discards the objects,
198
+ threads, and any other state or context associated with the isolate.
199
+ None of the manually attached threads targeted by this function may be executing
200
+ Java code at the time when this function is called or at any point in the future
201
+ or this will cause entirely undefined (and likely fatal) behavior.
202
+ Returns 0 on success, or a non-zero value on (non-fatal) failure.
203
+ """ ,
204
+ THREAD_TERMINATION_NOTE ,
205
+ })
188
206
@ CEntryPointOptions (prologue = NoPrologue .class , epilogue = NoEpilogue .class , nameTransformation = NameTransformation .class )
189
207
public static int detachAllThreadsAndTearDownIsolate (IsolateThread isolateThread ) {
190
208
int result = CEntryPointActions .enter (isolateThread );
0 commit comments