Author: dick
Date: 2006-05-25 09:33:49 -0400 (Thu, 25 May 2006)
New Revision: 61107
Modified:
branches/mono-1-1-13/mono/mono/io-layer/ChangeLog
branches/mono-1-1-13/mono/mono/io-layer/handles.c
branches/mono-1-1-13/mono/mono/io-layer/processes.c
branches/mono-1-1-13/mono/mono/io-layer/shared.c
branches/mono-1-1-13/mono/mono/io-layer/threads.c
branches/mono-1-1-13/mono/mono/io-layer/threads.h
branches/mono-1-1-13/mono/mono/metadata/ChangeLog
branches/mono-1-1-13/mono/mono/metadata/appdomain.c
branches/mono-1-1-13/mono/mono/metadata/threads.c
branches/mono-1-1-13/mono/mono/metadata/threads.h
Log:
2006-05-24 Dick Porter <[EMAIL PROTECTED]>
* processes.c (process_set_current): Don't take an extra reference
if we have to create our own process handle. Fixes bug 78241
again.
* threads.c (_wapi_thread_signal_self): Renamed from
_wapi_thread_abandon_mutexes, also sets the thread state to
signalled and drops a reference. Called by the runtime when the
main thread cleans itself up.
* handles.c (handle_cleanup): As a last resort, unref every shared
handle as the process is now exiting.
2006-05-24 Dick Porter <[EMAIL PROTECTED]>
* threads.c (mono_thread_cleanup): Move the threading cleanup out
of mono_thread_manage and back into its own function, so it can be
called after the finalizer thread has finished.
* appdomain.c (mono_runtime_cleanup): Call mono_thread_cleanup
Modified: branches/mono-1-1-13/mono/mono/io-layer/ChangeLog
===================================================================
--- branches/mono-1-1-13/mono/mono/io-layer/ChangeLog 2006-05-25 11:41:52 UTC
(rev 61106)
+++ branches/mono-1-1-13/mono/mono/io-layer/ChangeLog 2006-05-25 13:33:49 UTC
(rev 61107)
@@ -1,3 +1,17 @@
+2006-05-24 Dick Porter <[EMAIL PROTECTED]>
+
+ * processes.c (process_set_current): Don't take an extra reference
+ if we have to create our own process handle. Fixes bug 78241
+ again.
+
+ * threads.c (_wapi_thread_signal_self): Renamed from
+ _wapi_thread_abandon_mutexes, also sets the thread state to
+ signalled and drops a reference. Called by the runtime when the
+ main thread cleans itself up.
+
+ * handles.c (handle_cleanup): As a last resort, unref every shared
+ handle as the process is now exiting.
+
2006-05-16 Dick Porter <[EMAIL PROTECTED]>
* processes.c (process_set_termination_details): Unref the handle
Modified: branches/mono-1-1-13/mono/mono/io-layer/handles.c
===================================================================
--- branches/mono-1-1-13/mono/mono/io-layer/handles.c 2006-05-25 11:41:52 UTC
(rev 61106)
+++ branches/mono-1-1-13/mono/mono/io-layer/handles.c 2006-05-25 13:33:49 UTC
(rev 61107)
@@ -135,7 +135,37 @@
static void handle_cleanup (void)
{
+ int i, j, k;
+
_wapi_process_signal_self ();
+
+ /* Every shared handle we were using ought really to be closed
+ * by now, but to make sure just blow them all away. The
+ * exiting finalizer thread in particular races us to the
+ * program exit and doesn't always win, so it can be left
+ * cluttering up the shared file. Anything else left over is
+ * really a bug.
+ */
+ for(i = SLOT_INDEX (0); _wapi_private_handles[i] != NULL; i++) {
+ for(j = SLOT_OFFSET (0); j < _WAPI_HANDLE_INITIAL_COUNT; j++) {
+ struct _WapiHandleUnshared *handle_data =
&_wapi_private_handles[i][j];
+ int type = handle_data->type;
+
+
+ if (_WAPI_SHARED_HANDLE (type)) {
+ gpointer handle = GINT_TO_POINTER
(i*_WAPI_HANDLE_INITIAL_COUNT+j);
+
+ for(k = handle_data->ref; k > 0; k--) {
+#ifdef DEBUG
+ g_message ("%s: unreffing %s handle
%p", __func__, _wapi_handle_typename[type], handle);
+#endif
+
+ _wapi_handle_unref (handle);
+ }
+ }
+ }
+ }
+
_wapi_shm_semaphores_remove ();
}
@@ -504,8 +534,7 @@
InterlockedIncrement (&shared->handle_refs);
#ifdef DEBUG
- g_message ("%s: Allocated new handle %p referencing 0x%x", __func__,
- handle, offset);
+ g_message ("%s: Allocated new handle %p referencing 0x%x (shared refs
%d)", __func__, handle, offset, shared->handle_refs);
#endif
done:
@@ -979,6 +1008,10 @@
/* It's possible that this handle is already
* pointing at a deleted shared section
*/
+#ifdef DEBUG_REFS
+ g_message ("%s: %s handle %p shared refs before dec
%d", __func__, _wapi_handle_typename[type], handle, shared->handle_refs);
+#endif
+
if (shared->handle_refs > 0) {
shared->handle_refs--;
if (shared->handle_refs == 0) {
Modified: branches/mono-1-1-13/mono/mono/io-layer/processes.c
===================================================================
--- branches/mono-1-1-13/mono/mono/io-layer/processes.c 2006-05-25 11:41:52 UTC
(rev 61106)
+++ branches/mono-1-1-13/mono/mono/io-layer/processes.c 2006-05-25 13:33:49 UTC
(rev 61107)
@@ -942,11 +942,6 @@
g_warning ("%s: error creating process handle", __func__);
return;
}
-
- /* Make sure the new handle has a reference so it wont go away
- * until this process exits
- */
- _wapi_handle_ref (current_process);
}
gpointer _wapi_process_duplicate ()
Modified: branches/mono-1-1-13/mono/mono/io-layer/shared.c
===================================================================
--- branches/mono-1-1-13/mono/mono/io-layer/shared.c 2006-05-25 11:41:52 UTC
(rev 61106)
+++ branches/mono-1-1-13/mono/mono/io-layer/shared.c 2006-05-25 13:33:49 UTC
(rev 61107)
@@ -400,7 +400,7 @@
g_assert (thr_ret == 0);
#ifdef DEBUG
- g_message ("%s: Incrementing the process count", __func__);
+ g_message ("%s: Incrementing the process count (%d)", __func__,
_wapi_getpid ());
#endif
/* We only ever _unlock_ this semaphore, letting the kernel
@@ -412,7 +412,7 @@
_wapi_shm_sem_unlock (_WAPI_SHARED_SEM_PROCESS_COUNT);
#ifdef DEBUG
- g_message ("%s: Process count is now %d", __func__, semctl
(_wapi_sem_id, _WAPI_SHARED_SEM_PROCESS_COUNT, GETVAL));
+ g_message ("%s: Process count is now %d (%d)", __func__, semctl
(_wapi_sem_id, _WAPI_SHARED_SEM_PROCESS_COUNT, GETVAL), _wapi_getpid ());
#endif
_wapi_shm_sem_unlock (_WAPI_SHARED_SEM_PROCESS_COUNT_LOCK);
@@ -426,9 +426,10 @@
int proc_count;
#ifdef DEBUG
- g_message ("%s: Checking process count", __func__);
+ g_message ("%s: Checking process count (%d)", __func__,
+ _wapi_getpid ());
#endif
-
+
thr_ret = _wapi_shm_sem_lock (_WAPI_SHARED_SEM_PROCESS_COUNT_LOCK);
g_assert (thr_ret == 0);
@@ -451,7 +452,8 @@
* files
*/
#ifdef DEBUG
- g_message ("%s: Removing semaphores!", __func__);
+ g_message ("%s: Removing semaphores! (%d)", __func__,
+ _wapi_getpid ());
#endif
semctl (_wapi_sem_id, 0, IPC_RMID);
Modified: branches/mono-1-1-13/mono/mono/io-layer/threads.c
===================================================================
--- branches/mono-1-1-13/mono/mono/io-layer/threads.c 2006-05-25 11:41:52 UTC
(rev 61106)
+++ branches/mono-1-1-13/mono/mono/io-layer/threads.c 2006-05-25 13:33:49 UTC
(rev 61107)
@@ -66,8 +66,10 @@
WAPI_HANDLE_CAP_WAIT);
}
-/* Called by thread_exit(), but maybe by mono_thread_manage() too */
-void _wapi_thread_abandon_mutexes (gpointer handle)
+/* Called by thread_exit(), but maybe indirectly by
+ * mono_thread_manage() via mono_thread_signal_self() too
+ */
+static void _wapi_thread_abandon_mutexes (gpointer handle)
{
struct _WapiHandle_thread *thread_handle;
gboolean ok;
@@ -104,11 +106,8 @@
}
}
-/* Called by the thread creation code as a thread is finishing up, and
- * by ExitThread()
-*/
-static void thread_exit (guint32 exitstatus, gpointer handle) G_GNUC_NORETURN;
-static void thread_exit (guint32 exitstatus, gpointer handle)
+static void thread_set_termination_details (gpointer handle,
+ guint32 exitstatus)
{
struct _WapiHandle_thread *thread_handle;
gboolean ok;
@@ -124,18 +123,10 @@
if (ok == FALSE) {
g_warning ("%s: error looking up thread handle %p", __func__,
handle);
- /* exit the calling thread anyway, even though we
- * can't record the exit status and clean up the
- * private bits of handle data
- */
+
_wapi_handle_unlock_shared_handles ();
- pthread_exit (NULL);
+ return;
}
-
-#ifdef DEBUG
- g_message ("%s: Recording thread handle %p exit status", __func__,
- handle);
-#endif
thread_handle->exitstatus = exitstatus;
thread_handle->state = THREAD_STATE_EXITED;
@@ -150,10 +141,39 @@
g_message("%s: Recording thread handle %p id %ld status as %d",
__func__, handle, thread_handle->id, exitstatus);
#endif
-
+
/* The thread is no longer active, so unref it */
_wapi_handle_unref (handle);
+}
+void _wapi_thread_signal_self (guint32 exitstatus)
+{
+ gpointer handle;
+
+ handle = _wapi_thread_handle_from_id (pthread_self ());
+ if (handle == NULL) {
+ /* Something gone badly wrong... */
+ return;
+ }
+
+ thread_set_termination_details (handle, exitstatus);
+}
+
+/* Called by the thread creation code as a thread is finishing up, and
+ * by ExitThread()
+*/
+static void thread_exit (guint32 exitstatus, gpointer handle) G_GNUC_NORETURN;
+static void thread_exit (guint32 exitstatus, gpointer handle)
+{
+ if (_wapi_handle_issignalled (handle)) {
+ /* We must have already deliberately finished with
+ * this thread, so don't do any more now
+ */
+ pthread_exit (NULL);
+ }
+
+ thread_set_termination_details (handle, exitstatus);
+
/* Call pthread_exit() to call destructors and really exit the
* thread
*/
@@ -165,7 +185,8 @@
/* Drop the extra reference we take in thread_attach, now this
* thread is dead
*/
- _wapi_handle_unref (handle);
+
+ thread_set_termination_details (handle, 0);
}
static void thread_hash_init(void)
@@ -213,6 +234,10 @@
thread->id = pthread_self();
+#ifdef DEBUG
+ g_message ("%s: started thread id %ld", __func__, thread->id);
+#endif
+
if (thread->create_flags & CREATE_SUSPENDED) {
_wapi_thread_suspend (thread);
}
Modified: branches/mono-1-1-13/mono/mono/io-layer/threads.h
===================================================================
--- branches/mono-1-1-13/mono/mono/io-layer/threads.h 2006-05-25 11:41:52 UTC
(rev 61106)
+++ branches/mono-1-1-13/mono/mono/io-layer/threads.h 2006-05-25 13:33:49 UTC
(rev 61107)
@@ -63,7 +63,7 @@
/* Kludge alert! Making this visible outside io-layer is broken, but I
* can't find any w32 call that will let me do this.
*/
-extern void _wapi_thread_abandon_mutexes (gpointer handle);
+extern void _wapi_thread_signal_self (guint32 exitstatus);
G_END_DECLS
#endif /* _WAPI_THREADS_H_ */
Modified: branches/mono-1-1-13/mono/mono/metadata/ChangeLog
===================================================================
--- branches/mono-1-1-13/mono/mono/metadata/ChangeLog 2006-05-25 11:41:52 UTC
(rev 61106)
+++ branches/mono-1-1-13/mono/mono/metadata/ChangeLog 2006-05-25 13:33:49 UTC
(rev 61107)
@@ -1,3 +1,11 @@
+2006-05-24 Dick Porter <[EMAIL PROTECTED]>
+
+ * threads.c (mono_thread_cleanup): Move the threading cleanup out
+ of mono_thread_manage and back into its own function, so it can be
+ called after the finalizer thread has finished.
+
+ * appdomain.c (mono_runtime_cleanup): Call mono_thread_cleanup
+
2006-05-22 Zoltan Varga <[EMAIL PROTECTED]>
* threads.c (start_wrapper): Fix a missed guint32 tid declaration.
Modified: branches/mono-1-1-13/mono/mono/metadata/appdomain.c
===================================================================
--- branches/mono-1-1-13/mono/mono/metadata/appdomain.c 2006-05-25 11:41:52 UTC
(rev 61106)
+++ branches/mono-1-1-13/mono/mono/metadata/appdomain.c 2006-05-25 13:33:49 UTC
(rev 61107)
@@ -200,6 +200,8 @@
/* This ends up calling any pending pending (for at most 2 seconds) */
mono_gc_cleanup ();
+ mono_thread_cleanup ();
+
mono_network_cleanup ();
}
Modified: branches/mono-1-1-13/mono/mono/metadata/threads.c
===================================================================
--- branches/mono-1-1-13/mono/mono/metadata/threads.c 2006-05-25 11:41:52 UTC
(rev 61106)
+++ branches/mono-1-1-13/mono/mono/metadata/threads.c 2006-05-25 13:33:49 UTC
(rev 61107)
@@ -127,7 +127,7 @@
static MonoThreadAttachCB mono_thread_attach_cb = NULL;
/* function called at thread cleanup */
-static MonoThreadCleanupFunc mono_thread_cleanup = NULL;
+static MonoThreadCleanupFunc mono_thread_cleanup_fn = NULL;
/* function called when a new thread has been created */
static MonoThreadCallbacks *mono_thread_callbacks = NULL;
@@ -240,8 +240,8 @@
mono_gc_free_fixed (thread->culture_info);
mono_gc_free_fixed (thread->ui_culture_info);
- if (mono_thread_cleanup)
- mono_thread_cleanup (thread);
+ if (mono_thread_cleanup_fn)
+ mono_thread_cleanup_fn (thread);
}
static guint32 WINAPI start_wrapper(void *data)
@@ -1818,10 +1818,32 @@
GetCurrentProcess ();
}
+void mono_thread_cleanup (void)
+{
+#if !defined(PLATFORM_WIN32) && !defined(RUN_IN_SUBTHREAD)
+ /* The main thread must abandon any held mutexes (particularly
+ * important for named mutexes as they are shared across
+ * processes, see bug 74680.) This will happen when the
+ * thread exits, but if it's not running in a subthread it
+ * won't exit in time.
+ */
+ /* Using non-w32 API is a nasty kludge, but I couldn't find
+ * anything in the documentation that would let me do this
+ * here yet still be safe to call on windows.
+ */
+ _wapi_thread_signal_self (mono_environment_exitcode_get ());
+#endif
+
+ DeleteCriticalSection (&threads_mutex);
+ DeleteCriticalSection (&interlocked_mutex);
+ DeleteCriticalSection (&contexts_mutex);
+ CloseHandle (background_change_event);
+}
+
void
mono_threads_install_cleanup (MonoThreadCleanupFunc func)
{
- mono_thread_cleanup = func;
+ mono_thread_cleanup_fn = func;
}
void mono_install_thread_callbacks (MonoThreadCallbacks *callbacks)
@@ -1945,27 +1967,38 @@
/* Ignore background threads, we abort them later */
mono_monitor_enter (thread->synch_lock);
if (thread->state & ThreadState_Background) {
+ THREAD_DEBUG (g_message ("%s: ignoring background
thread %"G_GSIZE_FORMAT, __func__, (gsize)thread->tid));
mono_monitor_exit (thread->synch_lock);
return; /* just leave, ignore */
}
mono_monitor_exit (thread->synch_lock);
- if (mono_gc_is_finalizer_thread (thread))
+ if (mono_gc_is_finalizer_thread (thread)) {
+ THREAD_DEBUG (g_message ("%s: ignoring finalizer thread
%"G_GSIZE_FORMAT, __func__, (gsize)thread->tid));
return;
+ }
- if (thread == mono_thread_current ())
+ if (thread == mono_thread_current ()) {
+ THREAD_DEBUG (g_message ("%s: ignoring current thread
%"G_GSIZE_FORMAT, __func__, (gsize)thread->tid));
return;
+ }
- if (thread == mono_thread_get_main ())
+ if (thread == mono_thread_get_main ()) {
+ THREAD_DEBUG (g_message ("%s: ignoring main thread
%"G_GSIZE_FORMAT, __func__, (gsize)thread->tid));
return;
+ }
handle = OpenThread (THREAD_ALL_ACCESS, TRUE, thread->tid);
- if (handle == NULL)
+ if (handle == NULL) {
+ THREAD_DEBUG (g_message ("%s: ignoring unopenable
thread %"G_GSIZE_FORMAT, __func__, (gsize)thread->tid));
return;
+ }
wait->handles[wait->num]=handle;
wait->threads[wait->num]=thread;
wait->num++;
+
+ THREAD_DEBUG (g_message ("%s: adding thread %"G_GSIZE_FORMAT,
__func__, (gsize)thread->tid));
} else {
/* Just ignore the rest, we can't do anything with
* them yet
@@ -2065,20 +2098,6 @@
wait_for_tids (wait, INFINITE);
}
} while (wait->num > 0);
-
-#if !defined(PLATFORM_WIN32) && !defined(RUN_IN_SUBTHREAD)
- /* The main thread must abandon any held mutexes (particularly
- * important for named mutexes as they are shared across
- * processes, see bug 74680.) This will happen when the
- * thread exits, but if it's not running in a subthread it
- * won't exit in time.
- */
- /* Using non-w32 API is a nasty kludge, but I couldn't find
- * anything in the documentation that would let me do this
- * here yet still be safe to call on windows.
- */
- _wapi_thread_abandon_mutexes (NULL);
-#endif
/*
* give the subthreads a chance to really quit (this is mainly needed
Modified: branches/mono-1-1-13/mono/mono/metadata/threads.h
===================================================================
--- branches/mono-1-1-13/mono/mono/metadata/threads.h 2006-05-25 11:41:52 UTC
(rev 61106)
+++ branches/mono-1-1-13/mono/mono/metadata/threads.h 2006-05-25 13:33:49 UTC
(rev 61107)
@@ -22,6 +22,7 @@
extern void mono_thread_init (MonoThreadStartCB start_cb,
MonoThreadAttachCB attach_cb);
+extern void mono_thread_cleanup (void);
extern void mono_thread_manage(void);
extern void mono_thread_abort_all_other_threads (void);
extern void mono_thread_suspend_all_other_threads (void);
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches