@@ -442,15 +442,24 @@ jvmtiInterruptThread(jvmtiEnv *env,
442
442
J9JavaVM *vm = JAVAVM_FROM_ENV (env);
443
443
J9VMThread *currentThread = NULL ;
444
444
jvmtiError rc = JVMTI_ERROR_NONE;
445
+ #if JAVA_SPEC_VERSION >= 19
446
+ BOOLEAN isVirtualThread = FALSE ;
447
+ J9Class *vThreadClass = NULL ;
448
+ jclass vThreadJClass = NULL ;
449
+ #endif /* JAVA_SPEC_VERSION >= 19 */
445
450
446
451
Trc_JVMTI_jvmtiInterruptThread_Entry (env);
447
452
448
453
rc = getCurrentVMThread (vm, ¤tThread);
449
454
if (JVMTI_ERROR_NONE == rc) {
450
455
J9VMThread *targetThread = NULL ;
456
+ J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions ;
457
+ #if JAVA_SPEC_VERSION >= 19
458
+ JNIEnv *jniEnv = (JNIEnv *)currentThread;
459
+ #endif /* JAVA_SPEC_VERSION >= 19 */
460
+
461
+ vmFuncs->internalEnterVMFromJNI (currentThread);
451
462
452
- vm->internalVMFunctions ->internalEnterVMFromJNI (currentThread);
453
-
454
463
ENSURE_PHASE_LIVE (env);
455
464
ENSURE_CAPABILITY (env, can_signal_thread);
456
465
@@ -459,7 +468,15 @@ jvmtiInterruptThread(jvmtiEnv *env,
459
468
J9JVMTI_GETVMTHREAD_ERROR_ON_NULL_JTHREAD | J9JVMTI_GETVMTHREAD_ERROR_ON_DEAD_THREAD);
460
469
if (JVMTI_ERROR_NONE == rc) {
461
470
#if JAVA_SPEC_VERSION >= 19
462
- if (NULL != targetThread)
471
+ j9object_t threadObject = J9_JNI_UNWRAP_REFERENCE (thread);
472
+ isVirtualThread = IS_JAVA_LANG_VIRTUALTHREAD (currentThread, threadObject);
473
+
474
+ if (isVirtualThread && (NULL == vm->vThreadInterrupt )) {
475
+ vThreadClass = J9VMJAVALANGVIRTUALTHREAD_OR_NULL (vm);
476
+ vThreadJClass = (jclass)vmFuncs->j9jni_createLocalRef (jniEnv, vThreadClass->classObject );
477
+ }
478
+
479
+ if ((NULL != targetThread) && !isVirtualThread)
463
480
#endif /* JAVA_SPEC_VERSION >= 19 */
464
481
{
465
482
omrthread_interrupt (targetThread->osThread );
@@ -472,8 +489,30 @@ jvmtiInterruptThread(jvmtiEnv *env,
472
489
releaseVMThread (currentThread, targetThread, thread);
473
490
}
474
491
done:
475
- vm->internalVMFunctions ->internalExitVMToJNI (currentThread);
492
+ vmFuncs->internalExitVMToJNI (currentThread);
493
+
494
+ #if JAVA_SPEC_VERSION >= 19
495
+ if ((JVMTI_ERROR_NONE == rc) && isVirtualThread) {
496
+ if (NULL == vm->vThreadInterrupt ) {
497
+ jmethodID vThreadInterrupt = jniEnv->GetMethodID (vThreadJClass, " interrupt" , " ()V" );
498
+
499
+ if (NULL == vThreadInterrupt) {
500
+ rc = JVMTI_ERROR_INTERNAL;
501
+ goto exit;
502
+ }
503
+
504
+ vm->vThreadInterrupt = vThreadInterrupt;
505
+ }
506
+
507
+ jniEnv->CallObjectMethod (thread, vm->vThreadInterrupt );
508
+
509
+ if (jniEnv->ExceptionOccurred ()) {
510
+ rc = JVMTI_ERROR_INTERNAL;
511
+ }
512
+ }
476
513
}
514
+ exit:
515
+ #endif /* JAVA_SPEC_VERSION >= 19 */
477
516
478
517
TRACE_JVMTI_RETURN (jvmtiInterruptThread);
479
518
}
0 commit comments