static void reference_queue_clear_for_domain (MonoDomain *domain);
-static guint32
-guarded_wait (HANDLE handle, guint32 timeout, gboolean alertable)
+static MonoThreadInfoWaitRet
+guarded_wait (MonoThreadHandle *thread_handle, guint32 timeout, gboolean alertable)
{
- guint32 result;
+ MonoThreadInfoWaitRet result;
MONO_ENTER_GC_SAFE;
- result = WaitForSingleObjectEx (handle, timeout, alertable);
+ result = mono_thread_info_wait_one_handle (thread_handle, timeout, alertable);
MONO_EXIT_GC_SAFE;
return result;
mono_coop_mutex_lock (ud->mutex);
mono_coop_cond_signal (ud->cond);
mono_coop_mutex_unlock (ud->mutex);
+
+ g_free (ud);
}
/*
static inline gint
coop_cond_timedwait_alertable (MonoCoopCond *cond, MonoCoopMutex *mutex, guint32 timeout_ms, gboolean *alertable)
{
+ BreakCoopAlertableWaitUD *ud;
int res;
if (alertable) {
- BreakCoopAlertableWaitUD ud;
+ ud = g_new0 (BreakCoopAlertableWaitUD, 1);
+ ud->cond = cond;
+ ud->mutex = mutex;
- *alertable = FALSE;
- ud.cond = cond;
- ud.mutex = mutex;
- mono_thread_info_install_interrupt (break_coop_alertable_wait, &ud, alertable);
- if (*alertable)
+ mono_thread_info_install_interrupt (break_coop_alertable_wait, ud, alertable);
+ if (*alertable) {
+ g_free (ud);
return 0;
+ }
}
res = mono_coop_cond_timedwait (cond, mutex, timeout_ms);
if (alertable) {
mono_thread_info_uninstall_interrupt (alertable);
if (*alertable)
return 0;
+ else {
+ /* the interrupt token has not been taken by another
+ * thread, so it's our responsability to free it up. */
+ g_free (ud);
+ }
}
return res;
}
if (log_finalizers)
g_log ("mono-gc-finalizers", G_LOG_LEVEL_MESSAGE, "<%s at %p> Calling finalizer.", o->vtable->klass->name, o);
+ mono_profiler_gc_finalize_object_begin (o);
+
runtime_invoke (o, NULL, &exc, NULL);
+ mono_profiler_gc_finalize_object_end (o);
+
if (log_finalizers)
g_log ("mono-gc-finalizers", G_LOG_LEVEL_MESSAGE, "<%s at %p> Returned from finalizer.", o->vtable->klass->name, o);
mono_gc_finalize_notify ();
if (timeout == -1)
- timeout = INFINITE;
- if (timeout != INFINITE)
+ timeout = MONO_INFINITE_WAIT;
+ if (timeout != MONO_INFINITE_WAIT)
start = mono_msec_ticks ();
ret = TRUE;
for (;;) {
- if (timeout == INFINITE) {
+ if (timeout == MONO_INFINITE_WAIT) {
res = mono_coop_sem_wait (&req->done, MONO_SEM_FLAGS_ALERTABLE);
} else {
gint64 elapsed = mono_msec_ticks () - start;
mono_gc_finalize_threadpool_threads ();
}
- mono_profiler_appdomain_event (domain, MONO_PROFILE_END_UNLOAD);
-
done:
if (InterlockedDecrement (&req->ref) == 0) {
mono_coop_sem_destroy (&req->done);
ResetEvent (pending_done_event);
mono_gc_finalize_notify ();
/* g_print ("Waiting for pending finalizers....\n"); */
- guarded_wait (pending_done_event, INFINITE, TRUE);
+ MONO_ENTER_GC_SAFE;
+ WaitForSingleObjectEx (pending_done_event, INFINITE, TRUE);
+ MONO_EXIT_GC_SAFE;
/* g_print ("Done pending....\n"); */
#else
gboolean alerted = FALSE;
pending_done = FALSE;
mono_gc_finalize_notify ();
while (!pending_done) {
- coop_cond_timedwait_alertable (&pending_done_cond, &pending_done_mutex, INFINITE, &alerted);
+ coop_cond_timedwait_alertable (&pending_done_cond, &pending_done_mutex, MONO_INFINITE_WAIT, &alerted);
if (alerted)
break;
}
} else {
/* the C# code will check and throw the exception */
/* FIXME: missing !klass->blittable test, see bug #61134 */
- if ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_AUTO_LAYOUT)
+ if (mono_class_is_auto_layout (klass))
return (gpointer)-1;
return (char*)obj + sizeof (MonoObject);
}
finalize_domain_objects ();
+ mono_profiler_gc_finalize_begin ();
+
/* If finished == TRUE, mono_gc_cleanup has been called (from mono_runtime_cleanup),
* before the domain is unloaded.
*/
mono_gc_invoke_finalizers ();
+ mono_profiler_gc_finalize_end ();
+
mono_threads_join_threads ();
reference_queue_proccess_all ();
if (!gc_disabled) {
finished = TRUE;
if (mono_thread_internal_current () != gc_thread) {
+ int ret;
gint64 start_ticks = mono_msec_ticks ();
gint64 end_ticks = start_ticks + 2000;
}
if (!finalizer_thread_exited) {
- int ret;
-
/* Set a flag which the finalizer thread can check */
suspend_finalizers = TRUE;
mono_gc_suspend_finalizers ();
/* Wait for it to stop */
ret = guarded_wait (gc_thread->handle, 100, TRUE);
- if (ret == WAIT_TIMEOUT) {
+ if (ret == MONO_THREAD_INFO_WAIT_RET_TIMEOUT) {
/*
* The finalizer thread refused to exit. Make it stop.
*/
mono_thread_internal_stop (gc_thread);
ret = guarded_wait (gc_thread->handle, 100, TRUE);
- g_assert (ret != WAIT_TIMEOUT);
+ g_assert (ret != MONO_THREAD_INFO_WAIT_RET_TIMEOUT);
/* The thread can't set this flag */
finalizer_thread_exited = TRUE;
}
}
- int ret;
/* Wait for the thread to actually exit */
- ret = guarded_wait (gc_thread->handle, INFINITE, TRUE);
- g_assert (ret == WAIT_OBJECT_0);
+ ret = guarded_wait (gc_thread->handle, MONO_INFINITE_WAIT, TRUE);
+ g_assert (ret == MONO_THREAD_INFO_WAIT_RET_SUCCESS_0);
mono_thread_join (GUINT_TO_POINTER (gc_thread->tid));
g_assert (finalizer_thread_exited);