@@ -1549,7 +1549,7 @@ threadControl_resumeAll(void)
15491549 * resume any vthread with a suspendCount == 1, and we want to ignore
15501550 * vthreads with a suspendCount > 0. Therefore we don't want
15511551 * ResumeAllVirtualThreads resuming these vthreads. We must first
1552- * build a list of them to pass to as the exclude list.
1552+ * build a list of them to pass as the exclude list.
15531553 */
15541554 enumerateOverThreadList (env , & runningVThreads , excludeCountHelper ,
15551555 & excludeCnt );
@@ -2117,28 +2117,25 @@ threadControl_onEventHandlerEntry(jbyte sessionID, EventInfo *evinfo, jobject cu
21172117}
21182118
21192119static void
2120- doPendingTasks (JNIEnv * env , ThreadNode * node )
2120+ doPendingTasks (JNIEnv * env , jthread thread , int pendingInterrupt , jobject pendingStop )
21212121{
21222122 /*
2123- * Take care of any pending interrupts/stops, and clear out
2124- * info on pending interrupts/stops.
2123+ * Take care of any pending interrupts/stops.
21252124 */
2126- if (node -> pendingInterrupt ) {
2125+ if (pendingInterrupt ) {
21272126 JVMTI_FUNC_PTR (gdata -> jvmti ,InterruptThread )
2128- (gdata -> jvmti , node -> thread );
2127+ (gdata -> jvmti , thread );
21292128 /*
21302129 * TO DO: Log error
21312130 */
2132- node -> pendingInterrupt = JNI_FALSE ;
21332131 }
21342132
2135- if (node -> pendingStop != NULL ) {
2133+ if (pendingStop != NULL ) {
21362134 JVMTI_FUNC_PTR (gdata -> jvmti ,StopThread )
2137- (gdata -> jvmti , node -> thread , node -> pendingStop );
2135+ (gdata -> jvmti , thread , pendingStop );
21382136 /*
21392137 * TO DO: Log error
21402138 */
2141- tossGlobalRef (env , & (node -> pendingStop ));
21422139 }
21432140}
21442141
@@ -2147,35 +2144,44 @@ threadControl_onEventHandlerExit(EventIndex ei, jthread thread,
21472144 struct bag * eventBag )
21482145{
21492146 ThreadNode * node ;
2147+ JNIEnv * env = getEnv ();
21502148
21512149 log_debugee_location ("threadControl_onEventHandlerExit()" , thread , NULL , 0 );
21522150
21532151 if (ei == EI_THREAD_END ) {
2154- eventHandler_lock (); /* for proper lock order */
2155- }
2156- debugMonitorEnter (threadLock );
2157-
2158- node = findRunningThread (thread );
2159- if (node == NULL ) {
2160- EXIT_ERROR (AGENT_ERROR_NULL_POINTER ,"thread list corrupted" );
2161- } else {
2162- JNIEnv * env ;
2163-
2164- env = getEnv ();
2165- if (ei == EI_THREAD_END ) {
2166- removeThread (env , node );
2167- node = NULL ; /* has been freed */
2168- } else {
2169- /* No point in doing this if the thread is about to die.*/
2170- doPendingTasks (env , node );
2171- node -> eventBag = eventBag ;
2172- node -> current_ei = 0 ;
2152+ eventHandler_lock (); /* for proper lock order - see removeThread() call below */
2153+ debugMonitorEnter (threadLock );
2154+ node = findRunningThread (thread );
2155+ if (node == NULL ) {
2156+ EXIT_ERROR (AGENT_ERROR_NULL_POINTER ,"thread list corrupted" );
21732157 }
2174- }
2175-
2176- debugMonitorExit (threadLock );
2177- if (ei == EI_THREAD_END ) {
2158+ removeThread (env , node ); // Grabs handlerLock, thus the reason for first grabbing it above.
2159+ node = NULL ; // We exiting the threadLock. No longer safe to access.
2160+ debugMonitorExit (threadLock );
21782161 eventHandler_unlock ();
2162+ } else {
2163+ debugMonitorEnter (threadLock );
2164+ node = findRunningThread (thread );
2165+ if (node == NULL ) {
2166+ EXIT_ERROR (AGENT_ERROR_NULL_POINTER ,"thread list corrupted" );
2167+ }
2168+ /* No need to do the following if the thread is about to die.*/
2169+ int pendingInterrupt = node -> pendingInterrupt ;
2170+ jobject pendingStop = node -> pendingStop ;
2171+ jthread thread = node -> thread ;
2172+ node -> pendingInterrupt = JNI_FALSE ;
2173+ node -> pendingStop = NULL ;
2174+ node -> eventBag = eventBag ;
2175+ node -> current_ei = 0 ;
2176+ node = NULL ; // We exiting the threadLock. No longer safe to access.
2177+ // doPendingTasks() may do an upcall to java, and we don't want to hold any
2178+ // locks when doing that. Thus we got all our node updates done first
2179+ // and can now exit the threadLock.
2180+ debugMonitorExit (threadLock );
2181+ doPendingTasks (env , thread , pendingInterrupt , pendingStop );
2182+ if (pendingStop != NULL ) {
2183+ tossGlobalRef (env , & pendingStop );
2184+ }
21792185 }
21802186}
21812187
@@ -2219,29 +2225,9 @@ threadControl_applicationThreadStatus(jthread thread,
22192225jvmtiError
22202226threadControl_interrupt (jthread thread )
22212227{
2222- ThreadNode * node ;
2223- jvmtiError error ;
2224-
2225- error = JVMTI_ERROR_NONE ;
2226-
22272228 log_debugee_location ("threadControl_interrupt()" , thread , NULL , 0 );
22282229
2229- debugMonitorEnter (threadLock );
2230-
2231- node = findThread (& runningThreads , thread );
2232- if ((node == NULL ) || !HANDLING_EVENT (node )) {
2233- error = JVMTI_FUNC_PTR (gdata -> jvmti ,InterruptThread )
2234- (gdata -> jvmti , thread );
2235- } else {
2236- /*
2237- * Hold any interrupts until after the event is processed.
2238- */
2239- node -> pendingInterrupt = JNI_TRUE ;
2240- }
2241-
2242- debugMonitorExit (threadLock );
2243-
2244- return error ;
2230+ return JVMTI_FUNC_PTR (gdata -> jvmti ,InterruptThread )(gdata -> jvmti , thread );
22452231}
22462232
22472233void
@@ -2308,26 +2294,20 @@ threadControl_saveCLEInfo(JNIEnv *env, jthread thread, EventIndex ei,
23082294 debugMonitorExit (threadLock );
23092295}
23102296
2297+ /*
2298+ * Support for getting an interrupt in an application thread while doing
2299+ * a debugMonitorWait().
2300+ */
23112301void
23122302threadControl_setPendingInterrupt (jthread thread )
23132303{
23142304 ThreadNode * node ;
23152305
2316- /*
2317- * vmTestbase/nsk/jdb/kill/kill001/kill001.java seems to be the only code
2318- * that triggers this function. Is uses ThreadReference.Stop.
2319- *
2320- * Since ThreadReference.Stop is not supported for vthreads, we should never
2321- * get here with a vthread.
2322- */
2323- JDI_ASSERT (!isVThread (thread ));
2324-
23252306 debugMonitorEnter (threadLock );
23262307
2327- node = findThread (& runningThreads , thread );
2328- if (node != NULL ) {
2329- node -> pendingInterrupt = JNI_TRUE ;
2330- }
2308+ node = findRunningThread (thread );
2309+ JDI_ASSERT (node != NULL );
2310+ node -> pendingInterrupt = JNI_TRUE ;
23312311
23322312 debugMonitorExit (threadLock );
23332313}
@@ -2512,23 +2492,13 @@ threadControl_setEventMode(jvmtiEventMode mode, EventIndex ei, jthread thread)
25122492}
25132493
25142494/*
2515- * Returns the current thread, if the thread has generated at least
2516- * one event, and has not generated a thread end event.
2495+ * Returns the current thread.
25172496 */
25182497jthread
25192498threadControl_currentThread (void )
25202499{
2521- jthread thread ;
2522-
2523- debugMonitorEnter (threadLock );
2524- {
2525- ThreadNode * node ;
2526-
2527- node = findThread (& runningThreads , NULL );
2528- thread = (node == NULL ) ? NULL : node -> thread ;
2529- }
2530- debugMonitorExit (threadLock );
2531-
2500+ jthread thread = NULL ;
2501+ jvmtiError error = JVMTI_FUNC_PTR (gdata -> jvmti ,GetCurrentThread )(gdata -> jvmti , & thread );
25322502 return thread ;
25332503}
25342504
@@ -2670,6 +2640,7 @@ dumpThread(ThreadNode *node) {
26702640 tty_message ("\tthreadState: 0x%x" , getThreadState (node ));
26712641 tty_message ("\ttoBeResumed: %d" , node -> toBeResumed );
26722642 tty_message ("\tis_vthread: %d" , node -> is_vthread );
2643+ tty_message ("\tpendingInterrupt: %d" , node -> pendingInterrupt );
26732644 tty_message ("\tcurrentInvoke.pending: %d" , node -> currentInvoke .pending );
26742645 tty_message ("\tcurrentInvoke.started: %d" , node -> currentInvoke .started );
26752646 tty_message ("\tcurrentInvoke.available: %d" , node -> currentInvoke .available );
0 commit comments