[jit] Avoid licm for volatile variables, ssa ignores them so we can't detect whenever...
[mono.git] / mono / io-layer / handles.c
index 613d121f8df76ed78427e4d73c44ecf0237320d4..146c275cb5de7ba3198e16624933bd8b0398d963 100644 (file)
@@ -13,6 +13,7 @@
 #include <pthread.h>
 #include <errno.h>
 #include <unistd.h>
+#include <signal.h>
 #include <string.h>
 #include <sys/types.h>
 #ifdef HAVE_SYS_SOCKET_H
@@ -173,7 +174,7 @@ pid_t _wapi_getpid (void)
 }
 
 
-static mono_mutex_t scan_mutex = MONO_MUTEX_INITIALIZER;
+static mono_mutex_t scan_mutex;
 
 static void handle_cleanup (void)
 {
@@ -189,29 +190,8 @@ static void handle_cleanup (void)
        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;
                        gpointer handle = GINT_TO_POINTER (i*_WAPI_HANDLE_INITIAL_COUNT+j);
-                       
-                       if (_WAPI_SHARED_HANDLE (type)) {
-                               if (type == WAPI_HANDLE_THREAD) {
-                                       /* Special-case thread handles
-                                        * because they need extra
-                                        * cleanup.  This also avoids
-                                        * a race condition between
-                                        * the application exit and
-                                        * the finalizer thread - if
-                                        * it finishes up between now
-                                        * and actual app termination
-                                        * it will find all its handle
-                                        * details have been blown
-                                        * away, so this sets those
-                                        * anyway.
-                                        */
-                                       g_assert (0); /*This condition is freaking impossible*/
-                                       _wapi_thread_set_termination_details (handle, 0);
-                               }
-                       }
-                               
+
                        for(k = handle_data->ref; k > 0; k--) {
                                DEBUG ("%s: unreffing %s handle %p", __func__, _wapi_handle_typename[type], handle);
                                        
@@ -279,12 +259,15 @@ wapi_init (void)
        if (_wapi_shm_enabled ())
                _wapi_collection_init ();
 #endif
+       _wapi_io_init ();
+       mono_mutex_init (&scan_mutex);
 
        _wapi_global_signal_handle = _wapi_handle_new (WAPI_HANDLE_EVENT, NULL);
 
        _wapi_global_signal_cond = &_WAPI_PRIVATE_HANDLES (GPOINTER_TO_UINT (_wapi_global_signal_handle)).signal_cond;
        _wapi_global_signal_mutex = &_WAPI_PRIVATE_HANDLES (GPOINTER_TO_UINT (_wapi_global_signal_handle)).signal_mutex;
 
+
        /* Using g_atexit here instead of an explicit function call in
         * a cleanup routine lets us cope when a third-party library
         * calls exit (eg if an X client loses the connection to its
@@ -300,9 +283,9 @@ wapi_cleanup (void)
        
        _wapi_has_shut_down = TRUE;
 
-       _wapi_critical_section_cleanup ();
        _wapi_error_cleanup ();
        _wapi_thread_cleanup ();
+       wapi_processes_cleanup ();
 }
 
 static void _wapi_handle_init_shared (struct _WapiHandleShared *handle,
@@ -321,10 +304,57 @@ static void _wapi_handle_init_shared (struct _WapiHandleShared *handle,
        }
 }
 
+static size_t _wapi_handle_struct_size (WapiHandleType type)
+{
+       size_t type_size;
+
+       switch (type) {
+               case WAPI_HANDLE_FILE: case WAPI_HANDLE_CONSOLE: case WAPI_HANDLE_PIPE:
+                       type_size = sizeof (struct _WapiHandle_file);
+                       break;
+               case WAPI_HANDLE_THREAD:
+                       type_size = sizeof (struct _WapiHandle_thread);
+                       break;
+               case WAPI_HANDLE_SEM:
+                       type_size = sizeof (struct _WapiHandle_sem);
+                       break;
+               case WAPI_HANDLE_MUTEX:
+                       type_size = sizeof (struct _WapiHandle_mutex);
+                       break;
+               case WAPI_HANDLE_EVENT:
+                       type_size = sizeof (struct _WapiHandle_event);
+                       break;
+               case WAPI_HANDLE_SOCKET:
+                       type_size = sizeof (struct _WapiHandle_socket);
+                       break;
+               case WAPI_HANDLE_FIND:
+                       type_size = sizeof (struct _WapiHandle_find);
+                       break;
+               case WAPI_HANDLE_PROCESS:
+                       type_size = sizeof (struct _WapiHandle_process);
+                       break;
+               case WAPI_HANDLE_NAMEDMUTEX:
+                       type_size = sizeof (struct _WapiHandle_namedmutex);
+                       break;
+               case WAPI_HANDLE_NAMEDSEM:
+                       type_size = sizeof (struct _WapiHandle_namedsem);
+                       break;
+               case WAPI_HANDLE_NAMEDEVENT:
+                       type_size = sizeof (struct _WapiHandle_namedevent);
+                       break;
+
+               default:
+                       g_error ("Unknown WapiHandleType: %d\n", type);
+       }
+
+       return type_size;
+}
+
 static void _wapi_handle_init (struct _WapiHandleUnshared *handle,
                               WapiHandleType type, gpointer handle_specific)
 {
        int thr_ret;
+       int type_size;
        
        g_assert (_wapi_has_shut_down == FALSE);
        
@@ -336,12 +366,13 @@ static void _wapi_handle_init (struct _WapiHandleUnshared *handle,
                thr_ret = pthread_cond_init (&handle->signal_cond, NULL);
                g_assert (thr_ret == 0);
                                
-               thr_ret = mono_mutex_init (&handle->signal_mutex, NULL);
+               thr_ret = mono_mutex_init (&handle->signal_mutex);
                g_assert (thr_ret == 0);
 
                if (handle_specific != NULL) {
+                       type_size = _wapi_handle_struct_size (type);
                        memcpy (&handle->u, handle_specific,
-                               sizeof (handle->u));
+                               type_size);
                }
        }
 }
@@ -467,8 +498,6 @@ _wapi_handle_new (WapiHandleType type, gpointer handle_specific)
 
        g_assert(!_WAPI_FD_HANDLE(type));
        
-       pthread_cleanup_push ((void(*)(void *))mono_mutex_unlock_in_cleanup,
-                             (void *)&scan_mutex);
        thr_ret = mono_mutex_lock (&scan_mutex);
        g_assert (thr_ret == 0);
                
@@ -488,7 +517,6 @@ _wapi_handle_new (WapiHandleType type, gpointer handle_specific)
        
        thr_ret = mono_mutex_unlock (&scan_mutex);
        g_assert (thr_ret == 0);
-       pthread_cleanup_pop (0);
 
        if (handle_idx == 0) {
                /* We ran out of slots */
@@ -551,8 +579,6 @@ gpointer _wapi_handle_new_from_offset (WapiHandleType type, guint32 offset,
                InterlockedExchange ((gint32 *)&shared->timestamp, now);
        }
                
-       pthread_cleanup_push ((void(*)(void *))mono_mutex_unlock_in_cleanup,
-                             (void *)&scan_mutex);
        thr_ret = mono_mutex_lock (&scan_mutex);
        g_assert (thr_ret == 0);
 
@@ -573,7 +599,6 @@ gpointer _wapi_handle_new_from_offset (WapiHandleType type, guint32 offset,
 first_pass_done:
        thr_ret = mono_mutex_unlock (&scan_mutex);
        g_assert (thr_ret == 0);
-       pthread_cleanup_pop (0);
 
        if (handle != INVALID_HANDLE_VALUE) {
                _wapi_handle_ref (handle);
@@ -601,8 +626,6 @@ first_pass_done:
                goto done;
        }
        
-       pthread_cleanup_push ((void(*)(void *))mono_mutex_unlock_in_cleanup,
-                             (void *)&scan_mutex);
        thr_ret = mono_mutex_lock (&scan_mutex);
        g_assert (thr_ret == 0);
        
@@ -618,7 +641,6 @@ first_pass_done:
                
        thr_ret = mono_mutex_unlock (&scan_mutex);
        g_assert (thr_ret == 0);
-       pthread_cleanup_pop (0);
                
        /* Make sure we left the space for fd mappings */
        g_assert (handle_idx >= _wapi_fd_reserve);
@@ -641,8 +663,6 @@ init_handles_slot (int idx)
 {
        int thr_ret;
 
-       pthread_cleanup_push ((void(*)(void *))mono_mutex_unlock_in_cleanup,
-                                                 (void *)&scan_mutex);
        thr_ret = mono_mutex_lock (&scan_mutex);
        g_assert (thr_ret == 0);
 
@@ -654,7 +674,6 @@ init_handles_slot (int idx)
 
        thr_ret = mono_mutex_unlock (&scan_mutex);
        g_assert (thr_ret == 0);
-       pthread_cleanup_pop (0);
 }
 
 gpointer _wapi_handle_new_fd (WapiHandleType type, int fd,
@@ -760,8 +779,6 @@ _wapi_handle_foreach (WapiHandleType type,
        guint32 i, k;
        int thr_ret;
 
-       pthread_cleanup_push ((void(*)(void *))mono_mutex_unlock_in_cleanup,
-                             (void *)&scan_mutex);
        thr_ret = mono_mutex_lock (&scan_mutex);
        g_assert (thr_ret == 0);
 
@@ -781,7 +798,6 @@ _wapi_handle_foreach (WapiHandleType type,
 
        thr_ret = mono_mutex_unlock (&scan_mutex);
        g_assert (thr_ret == 0);
-       pthread_cleanup_pop (0);
 }
 
 /* This might list some shared handles twice if they are already
@@ -805,8 +821,6 @@ gpointer _wapi_search_handle (WapiHandleType type,
        gboolean found = FALSE;
        int thr_ret;
 
-       pthread_cleanup_push ((void(*)(void *))mono_mutex_unlock_in_cleanup,
-                             (void *)&scan_mutex);
        thr_ret = mono_mutex_lock (&scan_mutex);
        g_assert (thr_ret == 0);
        
@@ -834,7 +848,6 @@ gpointer _wapi_search_handle (WapiHandleType type,
 
        thr_ret = mono_mutex_unlock (&scan_mutex);
        g_assert (thr_ret == 0);
-       pthread_cleanup_pop (0);
 
        if (!found && search_shared && _WAPI_SHARED_HANDLE (type)) {
                /* Not found yet, so search the shared memory too */
@@ -1077,7 +1090,6 @@ static void _wapi_handle_unref_full (gpointer handle, gboolean ignore_private_bu
                        g_assert (thr_ret == 0);
                }
                
-               pthread_cleanup_push ((void(*)(void *))mono_mutex_unlock_in_cleanup, (void *)&scan_mutex);
                thr_ret = mono_mutex_lock (&scan_mutex);
 
                DEBUG ("%s: Destroying handle %p", __func__, handle);
@@ -1133,7 +1145,6 @@ static void _wapi_handle_unref_full (gpointer handle, gboolean ignore_private_bu
 
                thr_ret = mono_mutex_unlock (&scan_mutex);
                g_assert (thr_ret == 0);
-               pthread_cleanup_pop (0);
 
                if (early_exit)
                        return;
@@ -1346,7 +1357,7 @@ gboolean DuplicateHandle (gpointer srcprocess, gpointer src,
        if (src == _WAPI_PROCESS_CURRENT) {
                *target = _wapi_process_duplicate ();
        } else if (src == _WAPI_THREAD_CURRENT) {
-               *target = _wapi_thread_duplicate ();
+               g_assert_not_reached ();
        } else {
                _wapi_handle_ref (src);
                *target = src;
@@ -1761,6 +1772,9 @@ gboolean _wapi_handle_get_or_set_share (dev_t device, ino_t inode,
  */
 static void _wapi_handle_check_share_by_pid (struct _WapiFileShare *share_info)
 {
+#if defined(__native_client__)
+       g_assert_not_reached ();
+#else
        if (kill (share_info->opened_by_pid, 0) == -1 &&
            (errno == ESRCH ||
             errno == EPERM)) {
@@ -1772,6 +1786,7 @@ static void _wapi_handle_check_share_by_pid (struct _WapiFileShare *share_info)
 
                _wapi_free_share_info (share_info);
        }
+#endif
 }
 
 #ifdef __linux__
@@ -1930,8 +1945,6 @@ void _wapi_handle_dump (void)
        guint32 i, k;
        int thr_ret;
        
-       pthread_cleanup_push ((void(*)(void *))mono_mutex_unlock_in_cleanup,
-                             (void *)&scan_mutex);
        thr_ret = mono_mutex_lock (&scan_mutex);
        g_assert (thr_ret == 0);
        
@@ -1957,7 +1970,6 @@ void _wapi_handle_dump (void)
 
        thr_ret = mono_mutex_unlock (&scan_mutex);
        g_assert (thr_ret == 0);
-       pthread_cleanup_pop (0);
 }
 
 static void _wapi_shared_details (gpointer handle_info)
@@ -1980,8 +1992,6 @@ void _wapi_handle_update_refs (void)
        thr_ret = _wapi_shm_sem_lock (_WAPI_SHARED_SEM_FILESHARE);
        g_assert(thr_ret == 0);
 
-       pthread_cleanup_push ((void(*)(void *))mono_mutex_unlock_in_cleanup,
-                             (void *)&scan_mutex);
        thr_ret = mono_mutex_lock (&scan_mutex);
        
        for(i = SLOT_INDEX (0); i < _wapi_private_handle_slot_count; i++) {
@@ -2016,7 +2026,6 @@ void _wapi_handle_update_refs (void)
 
        thr_ret = mono_mutex_unlock (&scan_mutex);
        g_assert (thr_ret == 0);
-       pthread_cleanup_pop (0);
        
        thr_ret = _wapi_shm_sem_unlock (_WAPI_SHARED_SEM_FILESHARE);