#include <mono/metadata/gc-internal.h>
#include <mono/metadata/marshal.h> /* for mono_delegate_free_ftnptr () */
#include <mono/metadata/attach.h>
-#if HAVE_SEMAPHORE_H
-#include <semaphore.h>
-/* we do this only for known working systems (OSX for example
- * has the header and functions, but they don't work at all): in other cases
- * we fall back to the io-layer slightly slower and signal-unsafe Event.
- */
-#if defined (__linux__)
-#define USE_POSIX_SEM 1
-#endif
-#endif
+#include <mono/utils/mono-semaphore.h>
-#ifndef PLATFORM_WIN32
+#ifndef HOST_WIN32
#include <pthread.h>
#endif
static GSList *domains_to_finalize= NULL;
static MonoMList *threads_to_finalize = NULL;
-static MonoThread *gc_thread;
+static MonoInternalThread *gc_thread;
static void object_register_finalizer (MonoObject *obj, void (*callback)(void *, void*));
#endif
static void
-add_thread_to_finalize (MonoThread *thread)
+add_thread_to_finalize (MonoInternalThread *thread)
{
mono_finalizer_lock ();
if (!threads_to_finalize)
/* make sure the finalizer is not called again if the object is resurrected */
object_register_finalizer (obj, NULL);
- if (o->vtable->klass == mono_get_thread_class ()) {
- MonoThread *t = (MonoThread*)o;
+ if (o->vtable->klass == mono_defaults.internal_thread_class) {
+ MonoInternalThread *t = (MonoInternalThread*)o;
- if (mono_gc_is_finalizer_thread (t))
+ if (mono_gc_is_finalizer_internal_thread (t))
/* Avoid finalizing ourselves */
return;
MonoDelegate* del = (MonoDelegate*)o;
if (del->delegate_trampoline)
mono_delegate_free_ftnptr ((MonoDelegate*)o);
+ mono_domain_set_internal (caller_domain);
return;
}
mono_gc_finalize_threadpool_threads (void)
{
while (threads_to_finalize) {
- MonoThread *thread = (MonoThread*) mono_mlist_get_data (threads_to_finalize);
+ MonoInternalThread *thread = (MonoInternalThread*) mono_mlist_get_data (threads_to_finalize);
/* Force finalization of the thread. */
thread->threadpool_thread = FALSE;
{
#if HAVE_BOEHM_GC
guint offset = 0;
- MonoDomain *domain = obj->vtable->domain;
+ MonoDomain *domain;
+
+ if (obj == NULL)
+ mono_raise_exception (mono_get_exception_argument_null ("obj"));
+
+ domain = obj->vtable->domain;
#ifndef GC_DEBUG
/* This assertion is not valid when GC_DEBUG is defined */
GC_REGISTER_FINALIZER_NO_ORDER ((char*)obj - offset, callback, GUINT_TO_POINTER (offset), NULL, NULL);
#elif defined(HAVE_SGEN_GC)
+ if (obj == NULL)
+ mono_raise_exception (mono_get_exception_argument_null ("obj"));
+
mono_gc_register_for_finalization (obj, callback);
#endif
}
guint32 res;
HANDLE done_event;
- if (mono_thread_current () == gc_thread)
+ if (mono_thread_internal_current () == gc_thread)
/* We are called from inside a finalizer, not much we can do here */
return FALSE;
if (!mono_gc_pending_finalizers ())
return;
- if (mono_thread_current () == gc_thread)
+ if (mono_thread_internal_current () == gc_thread)
/* Avoid deadlocks */
return;
}
+MonoBoolean
+GCHandle_CheckCurrentDomain (guint32 gchandle)
+{
+ return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
+}
+
#ifndef HAVE_NULL_GC
-#if USE_POSIX_SEM
-static sem_t finalizer_sem;
+#ifdef MONO_HAS_SEMAPHORES
+static MonoSemType finalizer_sem;
#endif
static HANDLE finalizer_event;
static volatile gboolean finished=FALSE;
mono_gc_finalize_notify (void)
{
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": prodding finalizer");
+ g_message ( "%s: prodding finalizer", __func__);
#endif
-#if USE_POSIX_SEM
- sem_post (&finalizer_sem);
+#ifdef MONO_HAS_SEMAPHORES
+ MONO_SEM_POST (&finalizer_sem);
#else
SetEvent (finalizer_event);
#endif
/* Wait to be notified that there's at least one
* finaliser to run
*/
-#if USE_POSIX_SEM
- sem_wait (&finalizer_sem);
+
+ g_assert (mono_domain_get () == mono_get_root_domain ());
+
+#ifdef MONO_HAS_SEMAPHORES
+ MONO_SEM_WAIT (&finalizer_sem);
#else
/* Use alertable=FALSE since we will be asked to exit using the event too */
WaitForSingleObjectEx (finalizer_event, INFINITE, FALSE);
return 0;
}
+#ifdef HAVE_SGEN_GC
+#define GC_dont_gc 0
+#endif
+
void
mono_gc_init (void)
{
mono_gc_base_init ();
- if (g_getenv ("GC_DONT_GC")) {
+ if (GC_dont_gc || g_getenv ("GC_DONT_GC")) {
gc_disabled = TRUE;
return;
}
if (finalizer_event == NULL || pending_done_event == NULL || shutdown_event == NULL) {
g_assert_not_reached ();
}
-#if USE_POSIX_SEM
- sem_init (&finalizer_sem, 0, 0);
+#ifdef MONO_HAS_SEMAPHORES
+ MONO_SEM_INIT (&finalizer_sem, 0);
#endif
gc_thread = mono_thread_create_internal (mono_domain_get (), finalizer_thread, NULL, FALSE);
mono_gc_cleanup (void)
{
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": cleaning up finalizer");
+ g_message ("%s: cleaning up finalizer", __func__);
#endif
if (!gc_disabled) {
ResetEvent (shutdown_event);
finished = TRUE;
- if (mono_thread_current () != gc_thread) {
+ if (mono_thread_internal_current () != gc_thread) {
mono_gc_finalize_notify ();
/* Finishing the finalizer thread, so wait a little bit... */
/* MS seems to wait for about 2 seconds */
suspend_finalizers = TRUE;
/* Try to abort the thread, in the hope that it is running managed code */
- mono_thread_stop (gc_thread);
+ mono_thread_internal_stop (gc_thread);
/* Wait for it to stop */
ret = WaitForSingleObjectEx (gc_thread->handle, 100, TRUE);
#endif
+gboolean
+mono_gc_is_finalizer_internal_thread (MonoInternalThread *thread)
+{
+ return thread == gc_thread;
+}
+
/**
* mono_gc_is_finalizer_thread:
* @thread: the thread to test.
gboolean
mono_gc_is_finalizer_thread (MonoThread *thread)
{
- return thread == gc_thread;
-}
-
-static MonoGetIPFromSigCtxFunc get_ip_from_sigctx = NULL;
-
-void
-mono_install_get_ip_from_sigctx (MonoGetIPFromSigCtxFunc func)
-{
- get_ip_from_sigctx = func;
-}
-
-gpointer
-mono_gc_get_ip_from_sigctx (gpointer ctx)
-{
- g_assert (get_ip_from_sigctx);
- return get_ip_from_sigctx (ctx);
+ return mono_gc_is_finalizer_internal_thread (thread->internal_thread);
}