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

Reply via email to