mono_array_set (thread->cached_culture_info, MonoObject*, i, NULL);
}
- /* if the thread is not in the hash it has been removed already */
- if (!handle_remove (thread)) {
- /* This needs to be called even if handle_remove () fails */
- if (mono_thread_cleanup_fn)
- mono_thread_cleanup_fn (thread);
- return;
- }
- mono_release_type_locks (thread);
-
ensure_synch_cs_set (thread);
EnterCriticalSection (thread->synch_cs);
thread->state &= ~ThreadState_Background;
LeaveCriticalSection (thread->synch_cs);
+
+ /*
+ An interruption request has leaked to cleanup. Adjust the global counter.
+
+ This can happen is the abort source thread finds the abortee (this) thread
+ in unmanaged code. If this thread never trips back to managed code or check
+ the local flag it will be left set and positively unbalance the global counter.
+ Leaving the counter unbalanced will cause a performance degradation since all threads
+ will now keep checking their local flags all the time.
+ */
+ if (InterlockedExchange (&thread->interruption_requested, 0))
+ InterlockedDecrement (&thread_interruption_requested);
+
+ /* if the thread is not in the hash it has been removed already */
+ if (!handle_remove (thread)) {
+ /* This needs to be called even if handle_remove () fails */
+ if (mono_thread_cleanup_fn)
+ mono_thread_cleanup_fn (thread);
+ return;
+ }
+ mono_release_type_locks (thread);
+
mono_profiler_thread_end (thread->tid);
if (thread == mono_thread_internal_current ())
if (InterlockedCompareExchange (&thread->interruption_requested, 1, 0) == 1)
return NULL;
+ InterlockedIncrement (&thread_interruption_requested);
if (!running_managed || is_running_protected_wrapper ()) {
/* Can't stop while in unmanaged code. Increase the global interruption
request count. When exiting the unmanaged method the count will be
checked and the thread will be interrupted. */
- InterlockedIncrement (&thread_interruption_requested);
if (mono_thread_notify_pending_exc_fn && !running_managed)
/* The JIT will notify the thread about the interruption */
mono_thread_info_resume (mono_thread_info_get_tid (info));
return;
}
+ InterlockedIncrement (&thread_interruption_requested);
ji = mono_thread_info_get_last_managed (info);
protected_wrapper = ji && mono_threads_is_critical_method (ji->method);
* functions in the io-layer until the signal handler calls QueueUserAPC which will
* make it return.
*/
- InterlockedIncrement (&thread_interruption_requested);
#ifndef HOST_WIN32
interrupt_handle = wapi_prepare_interrupt_thread (thread->handle);
#endif