Merge pull request #2810 from kumpera/fix_hazard_free
[mono.git] / mono / io-layer / handles.c
index c6657dea405fae40128ca2d373287dabc312e384..f31d6cbfb4e1d984b52e866c5c3b5970c370d112 100644 (file)
@@ -6,6 +6,7 @@
  *
  * (C) 2002-2011 Novell, Inc.
  * Copyright 2011 Xamarin Inc
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
 #include <config.h>
 #include <mono/io-layer/wapi.h>
 #include <mono/io-layer/wapi-private.h>
 #include <mono/io-layer/handles-private.h>
-#include <mono/io-layer/misc-private.h>
 #include <mono/io-layer/shared.h>
-#include <mono/io-layer/collection.h>
 #include <mono/io-layer/process-private.h>
+#include <mono/io-layer/io-trace.h>
 
-#include <mono/utils/mono-mutex.h>
+#include <mono/utils/mono-os-mutex.h>
 #include <mono/utils/mono-proclib.h>
+#include <mono/utils/mono-threads.h>
+#include <mono/utils/mono-once.h>
+#include <mono/utils/mono-logger-internals.h>
 #undef DEBUG_REFS
 
-#if 0
-#define DEBUG(...) g_message(__VA_ARGS__)
-#else
-#define DEBUG(...)
-#endif
-
 static void (*_wapi_handle_ops_get_close_func (WapiHandleType type))(gpointer, gpointer);
 
-static WapiHandleCapability handle_caps[WAPI_HANDLE_COUNT]={0};
+static WapiHandleCapability handle_caps[WAPI_HANDLE_COUNT] = { (WapiHandleCapability)0 };
 static struct _WapiHandleOps *handle_ops[WAPI_HANDLE_COUNT]={
        NULL,
        &_wapi_file_ops,
@@ -125,11 +122,6 @@ static guint32 _wapi_private_handle_slot_count = 0;
 
 struct _WapiHandleSharedLayout *_wapi_shared_layout = NULL;
 
-/*
- * If SHM is enabled, this will point to shared memory, otherwise it will be NULL.
- */
-struct _WapiFileShareLayout *_wapi_fileshare_layout = NULL;
-
 /*
  * If SHM is disabled, this will point to a hash of _WapiFileShare structures, otherwise
  * it will be NULL. We use this instead of _wapi_fileshare_layout to avoid allocating a
@@ -138,8 +130,8 @@ struct _WapiFileShareLayout *_wapi_fileshare_layout = NULL;
 static GHashTable *file_share_hash;
 static mono_mutex_t file_share_hash_mutex;
 
-#define file_share_hash_lock() mono_mutex_lock (&file_share_hash_mutex)
-#define file_share_hash_unlock() mono_mutex_unlock (&file_share_hash_mutex)
+#define file_share_hash_lock() mono_os_mutex_lock (&file_share_hash_mutex)
+#define file_share_hash_unlock() mono_os_mutex_unlock (&file_share_hash_mutex)
 
 guint32 _wapi_fd_reserve;
 
@@ -198,8 +190,6 @@ static void handle_cleanup (void)
                        gpointer handle = GINT_TO_POINTER (i*_WAPI_HANDLE_INITIAL_COUNT+j);
 
                        for(k = handle_data->ref; k > 0; k--) {
-                               DEBUG ("%s: unreffing %s handle %p", __func__, _wapi_handle_typename[type], handle);
-                                       
                                _wapi_handle_unref_full (handle, TRUE);
                        }
                }
@@ -207,12 +197,11 @@ static void handle_cleanup (void)
        
        _wapi_shm_semaphores_remove ();
 
-       _wapi_shm_detach (WAPI_SHM_DATA);
-       _wapi_shm_detach (WAPI_SHM_FILESHARE);
+       g_free (_wapi_shared_layout);
 
        if (file_share_hash) {
                g_hash_table_destroy (file_share_hash);
-               mono_mutex_destroy (&file_share_hash_mutex);
+               mono_os_mutex_destroy (&file_share_hash_mutex);
        }
 
        for (i = 0; i < _WAPI_PRIVATE_MAX_SLOTS; ++i)
@@ -256,22 +245,12 @@ wapi_init (void)
        } while(_wapi_fd_reserve > _wapi_private_handle_count);
 
        _wapi_shm_semaphores_init ();
-       
-       _wapi_shared_layout = _wapi_shm_attach (WAPI_SHM_DATA);
+
+       _wapi_shared_layout = (_WapiHandleSharedLayout *)g_malloc0 (sizeof (_WapiHandleSharedLayout));
        g_assert (_wapi_shared_layout != NULL);
-       
-       if (_wapi_shm_enabled ()) {
-               /* This allocates a 4mb array, so do it only if SHM is enabled */
-               _wapi_fileshare_layout = _wapi_shm_attach (WAPI_SHM_FILESHARE);
-               g_assert (_wapi_fileshare_layout != NULL);
-       }
-       
-#if !defined (DISABLE_SHARED_HANDLES)
-       if (_wapi_shm_enabled ())
-               _wapi_collection_init ();
-#endif
+
        _wapi_io_init ();
-       mono_mutex_init (&scan_mutex);
+       mono_os_mutex_init (&scan_mutex);
 
        _wapi_global_signal_handle = _wapi_handle_new (WAPI_HANDLE_EVENT, NULL);
 
@@ -372,7 +351,7 @@ 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);
+               thr_ret = mono_os_mutex_init (&handle->signal_mutex);
                g_assert (thr_ret == 0);
 
                if (handle_specific != NULL) {
@@ -499,12 +478,12 @@ _wapi_handle_new (WapiHandleType type, gpointer handle_specific)
 
        g_assert (_wapi_has_shut_down == FALSE);
                
-       DEBUG ("%s: Creating new handle of type %s", __func__,
+       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating new handle of type %s", __func__,
                   _wapi_handle_typename[type]);
 
        g_assert(!_WAPI_FD_HANDLE(type));
        
-       thr_ret = mono_mutex_lock (&scan_mutex);
+       thr_ret = mono_os_mutex_lock (&scan_mutex);
        g_assert (thr_ret == 0);
                
        while ((handle_idx = _wapi_handle_new_internal (type, handle_specific)) == 0) {
@@ -521,7 +500,7 @@ _wapi_handle_new (WapiHandleType type, gpointer handle_specific)
                _wapi_private_handle_slot_count ++;
        }
        
-       thr_ret = mono_mutex_unlock (&scan_mutex);
+       thr_ret = mono_os_mutex_unlock (&scan_mutex);
        g_assert (thr_ret == 0);
 
        if (handle_idx == 0) {
@@ -535,7 +514,7 @@ _wapi_handle_new (WapiHandleType type, gpointer handle_specific)
        
        handle = GUINT_TO_POINTER (handle_idx);
 
-       DEBUG ("%s: Allocated new handle %p", __func__, handle);
+       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Allocated new handle %p", __func__, handle);
        
        if (_WAPI_SHARED_HANDLE(type)) {
                /* Add the shared section too */
@@ -543,7 +522,6 @@ _wapi_handle_new (WapiHandleType type, gpointer handle_specific)
                
                ref = _wapi_handle_new_shared (type, handle_specific);
                if (ref == 0) {
-                       _wapi_handle_collect ();
                        ref = _wapi_handle_new_shared (type, handle_specific);
                        if (ref == 0) {
                                /* FIXME: grow the arrays */
@@ -553,7 +531,7 @@ _wapi_handle_new (WapiHandleType type, gpointer handle_specific)
                }
                
                _WAPI_PRIVATE_HANDLES(handle_idx).u.shared.offset = ref;
-               DEBUG ("%s: New shared handle at offset 0x%x", __func__,
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: New shared handle at offset 0x%x", __func__,
                           ref);
        }
                
@@ -571,7 +549,7 @@ gpointer _wapi_handle_new_from_offset (WapiHandleType type, guint32 offset,
        
        g_assert (_wapi_has_shut_down == FALSE);
        
-       DEBUG ("%s: Creating new handle of type %s to offset %d", __func__,
+       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating new handle of type %s to offset %d", __func__,
                   _wapi_handle_typename[type], offset);
 
        g_assert(!_WAPI_FD_HANDLE(type));
@@ -585,7 +563,7 @@ gpointer _wapi_handle_new_from_offset (WapiHandleType type, guint32 offset,
                InterlockedExchange ((gint32 *)&shared->timestamp, now);
        }
                
-       thr_ret = mono_mutex_lock (&scan_mutex);
+       thr_ret = mono_os_mutex_lock (&scan_mutex);
        g_assert (thr_ret == 0);
 
        for (i = SLOT_INDEX (0); i < _wapi_private_handle_slot_count; i++) {
@@ -603,13 +581,13 @@ gpointer _wapi_handle_new_from_offset (WapiHandleType type, guint32 offset,
        }
 
 first_pass_done:
-       thr_ret = mono_mutex_unlock (&scan_mutex);
+       thr_ret = mono_os_mutex_unlock (&scan_mutex);
        g_assert (thr_ret == 0);
 
        if (handle != INVALID_HANDLE_VALUE) {
                _wapi_handle_ref (handle);
 
-               DEBUG ("%s: Returning old handle %p referencing 0x%x",
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Returning old handle %p referencing 0x%x",
                           __func__, handle, offset);
                return (handle);
        }
@@ -620,19 +598,19 @@ first_pass_done:
        
        if (shared->type == WAPI_HANDLE_UNUSED) {
                /* Someone deleted this handle while we were working */
-               DEBUG ("%s: Handle at 0x%x unused", __func__, offset);
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Handle at 0x%x unused", __func__, offset);
                goto done;
        }
 
        if (shared->type != type) {
-               DEBUG ("%s: Wrong type at %d 0x%x! Found %s wanted %s",
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Wrong type at %d 0x%x! Found %s wanted %s",
                           __func__, offset, offset,
                           _wapi_handle_typename[shared->type],
                           _wapi_handle_typename[type]);
                goto done;
        }
        
-       thr_ret = mono_mutex_lock (&scan_mutex);
+       thr_ret = mono_os_mutex_lock (&scan_mutex);
        g_assert (thr_ret == 0);
        
        while ((handle_idx = _wapi_handle_new_internal (type, NULL)) == 0) {
@@ -645,7 +623,7 @@ first_pass_done:
                _wapi_private_handle_slot_count ++;
        }
                
-       thr_ret = mono_mutex_unlock (&scan_mutex);
+       thr_ret = mono_os_mutex_unlock (&scan_mutex);
        g_assert (thr_ret == 0);
                
        /* Make sure we left the space for fd mappings */
@@ -656,7 +634,7 @@ first_pass_done:
        _WAPI_PRIVATE_HANDLES(handle_idx).u.shared.offset = offset;
        InterlockedIncrement ((gint32 *)&shared->handle_refs);
        
-       DEBUG ("%s: Allocated new handle %p referencing 0x%x (shared refs %d)", __func__, handle, offset, shared->handle_refs);
+       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Allocated new handle %p referencing 0x%x (shared refs %d)", __func__, handle, offset, shared->handle_refs);
        
 done:
        _wapi_handle_unlock_shared_handles ();
@@ -669,7 +647,7 @@ init_handles_slot (int idx)
 {
        int thr_ret;
 
-       thr_ret = mono_mutex_lock (&scan_mutex);
+       thr_ret = mono_os_mutex_lock (&scan_mutex);
        g_assert (thr_ret == 0);
 
        if (_wapi_private_handles [idx] == NULL) {
@@ -678,7 +656,7 @@ init_handles_slot (int idx)
                g_assert (_wapi_private_handles [idx]);
        }
 
-       thr_ret = mono_mutex_unlock (&scan_mutex);
+       thr_ret = mono_os_mutex_unlock (&scan_mutex);
        g_assert (thr_ret == 0);
 }
 
@@ -690,14 +668,14 @@ gpointer _wapi_handle_new_fd (WapiHandleType type, int fd,
        
        g_assert (_wapi_has_shut_down == FALSE);
        
-       DEBUG ("%s: Creating new handle of type %s", __func__,
+       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Creating new handle of type %s", __func__,
                   _wapi_handle_typename[type]);
        
        g_assert(_WAPI_FD_HANDLE(type));
        g_assert(!_WAPI_SHARED_HANDLE(type));
        
        if (fd >= _wapi_fd_reserve) {
-               DEBUG ("%s: fd %d is too big", __func__, fd);
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d is too big", __func__, fd);
 
                return(GUINT_TO_POINTER (_WAPI_HANDLE_INVALID));
        }
@@ -709,13 +687,13 @@ gpointer _wapi_handle_new_fd (WapiHandleType type, int fd,
        handle = &_WAPI_PRIVATE_HANDLES(fd);
        
        if (handle->type != WAPI_HANDLE_UNUSED) {
-               DEBUG ("%s: fd %d is already in use!", __func__, fd);
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: fd %d is already in use!", __func__, fd);
                /* FIXME: clean up this handle?  We can't do anything
                 * with the fd, cos thats the new one
                 */
        }
 
-       DEBUG ("%s: Assigning new fd handle %d", __func__, fd);
+       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Assigning new fd handle %d", __func__, fd);
 
        /* Prevent file share entries racing with us, when the file
         * handle is only half initialised
@@ -785,7 +763,7 @@ _wapi_handle_foreach (WapiHandleType type,
        guint32 i, k;
        int thr_ret;
 
-       thr_ret = mono_mutex_lock (&scan_mutex);
+       thr_ret = mono_os_mutex_lock (&scan_mutex);
        g_assert (thr_ret == 0);
 
        for (i = SLOT_INDEX (0); i < _wapi_private_handle_slot_count; i++) {
@@ -802,7 +780,7 @@ _wapi_handle_foreach (WapiHandleType type,
                }
        }
 
-       thr_ret = mono_mutex_unlock (&scan_mutex);
+       thr_ret = mono_os_mutex_unlock (&scan_mutex);
        g_assert (thr_ret == 0);
 }
 
@@ -827,7 +805,7 @@ gpointer _wapi_search_handle (WapiHandleType type,
        gboolean found = FALSE;
        int thr_ret;
 
-       thr_ret = mono_mutex_lock (&scan_mutex);
+       thr_ret = mono_os_mutex_lock (&scan_mutex);
        g_assert (thr_ret == 0);
        
        for (i = SLOT_INDEX (0); !found && i < _wapi_private_handle_slot_count; i++) {
@@ -852,12 +830,12 @@ gpointer _wapi_search_handle (WapiHandleType type,
                }
        }
 
-       thr_ret = mono_mutex_unlock (&scan_mutex);
+       thr_ret = mono_os_mutex_unlock (&scan_mutex);
        g_assert (thr_ret == 0);
 
        if (!found && search_shared && _WAPI_SHARED_HANDLE (type)) {
                /* Not found yet, so search the shared memory too */
-               DEBUG ("%s: Looking at other shared handles...", __func__);
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Looking at other shared handles...", __func__);
 
                for (i = 0; i < _WAPI_HANDLE_INITIAL_COUNT; i++) {
                        shared = &_wapi_shared_layout->handles[i];
@@ -878,7 +856,7 @@ gpointer _wapi_search_handle (WapiHandleType type,
                                        continue;
                                }
                                
-                               DEBUG ("%s: Opened tmp handle %p (type %s) from offset %d", __func__, ret, _wapi_handle_typename[type], i);
+                               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Opened tmp handle %p (type %s) from offset %d", __func__, ret, _wapi_handle_typename[type], i);
 
                                /* It's possible that the shared part
                                 * of this handle has now been blown
@@ -955,14 +933,9 @@ gint32 _wapi_search_handle_namespace (WapiHandleType type,
        
        g_assert(_WAPI_SHARED_HANDLE(type));
        
-       DEBUG ("%s: Lookup for handle named [%s] type %s", __func__,
+       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Lookup for handle named [%s] type %s", __func__,
                   utf8_name, _wapi_handle_typename[type]);
 
-       /* Do a handle collection before starting to look, so that any
-        * stale cruft gets removed
-        */
-       _wapi_handle_collect ();
-       
        thr_ret = _wapi_handle_lock_shared_handles ();
        g_assert (thr_ret == 0);
        
@@ -979,20 +952,20 @@ gint32 _wapi_search_handle_namespace (WapiHandleType type,
                        continue;
                }
 
-               DEBUG ("%s: found a shared namespace handle at 0x%x (type %s)", __func__, i, _wapi_handle_typename[shared_handle_data->type]);
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: found a shared namespace handle at 0x%x (type %s)", __func__, i, _wapi_handle_typename[shared_handle_data->type]);
 
                sharedns=(WapiSharedNamespace *)&shared_handle_data->u;
                        
-               DEBUG ("%s: name is [%s]", __func__, sharedns->name);
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: name is [%s]", __func__, sharedns->name);
 
                if (strcmp (sharedns->name, utf8_name) == 0) {
                        if (shared_handle_data->type != type) {
                                /* Its the wrong type, so fail now */
-                               DEBUG ("%s: handle 0x%x matches name but is wrong type: %s", __func__, i, _wapi_handle_typename[shared_handle_data->type]);
+                               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle 0x%x matches name but is wrong type: %s", __func__, i, _wapi_handle_typename[shared_handle_data->type]);
                                ret = -1;
                                goto done;
                        } else {
-                               DEBUG ("%s: handle 0x%x matches name and type", __func__, i);
+                               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle 0x%x matches name and type", __func__, i);
                                ret = i;
                                goto done;
                        }
@@ -1096,9 +1069,9 @@ static void _wapi_handle_unref_full (gpointer handle, gboolean ignore_private_bu
                        g_assert (thr_ret == 0);
                }
                
-               thr_ret = mono_mutex_lock (&scan_mutex);
+               thr_ret = mono_os_mutex_lock (&scan_mutex);
 
-               DEBUG ("%s: Destroying handle %p", __func__, handle);
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Destroying handle %p", __func__, handle);
                
                memcpy (&handle_data, &_WAPI_PRIVATE_HANDLES(idx),
                        sizeof (struct _WapiHandleUnshared));
@@ -1114,7 +1087,7 @@ static void _wapi_handle_unref_full (gpointer handle, gboolean ignore_private_bu
                         * now, but pthreads doesn't have a
                         * "unlock_and_destroy" atomic function.
                         */
-                       thr_ret = mono_mutex_destroy (&_WAPI_PRIVATE_HANDLES(idx).signal_mutex);
+                       thr_ret = mono_os_mutex_destroy (&_WAPI_PRIVATE_HANDLES(idx).signal_mutex);
                        /*WARNING gross hack to make cleanup not crash when exiting without the whole runtime teardown.*/
                        if (thr_ret == EBUSY && ignore_private_busy_handles) {
                                early_exit = TRUE;
@@ -1149,7 +1122,7 @@ static void _wapi_handle_unref_full (gpointer handle, gboolean ignore_private_bu
                        }
                }
 
-               thr_ret = mono_mutex_unlock (&scan_mutex);
+               thr_ret = mono_os_mutex_unlock (&scan_mutex);
                g_assert (thr_ret == 0);
 
                if (early_exit)
@@ -1191,7 +1164,7 @@ gboolean _wapi_handle_test_capabilities (gpointer handle,
        
        type = _WAPI_PRIVATE_HANDLES(idx).type;
 
-       DEBUG ("%s: testing 0x%x against 0x%x (%d)", __func__,
+       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: testing 0x%x against 0x%x (%d)", __func__,
                   handle_caps[type], caps, handle_caps[type] & caps);
        
        return((handle_caps[type] & caps) != 0);
@@ -1392,7 +1365,7 @@ again:
                gpointer handle = handles[i];
                guint32 idx = GPOINTER_TO_UINT(handle);
 
-               DEBUG ("%s: attempting to lock %p", __func__, handle);
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: attempting to lock %p", __func__, handle);
 
                type = _WAPI_PRIVATE_HANDLES(idx).type;
 
@@ -1401,7 +1374,7 @@ again:
                if (thr_ret != 0) {
                        /* Bummer */
                        
-                       DEBUG ("%s: attempt failed for %p: %s", __func__,
+                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: attempt failed for %p: %s", __func__,
                                   handle, strerror (thr_ret));
 
                        thr_ret = _wapi_handle_unlock_shared_handles ();
@@ -1426,7 +1399,7 @@ again:
                                iter=1;
                        }
                        
-                       DEBUG ("%s: Backing off for %d ms", __func__,
+                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Backing off for %d ms", __func__,
                                   iter*10);
                        _wapi_handle_spin (10 * iter);
                        
@@ -1434,7 +1407,7 @@ again:
                }
        }
        
-       DEBUG ("%s: Locked all handles", __func__);
+       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Locked all handles", __func__);
 
        count=0;
        *lowest=numhandles;
@@ -1445,7 +1418,7 @@ again:
                
                type = _WAPI_PRIVATE_HANDLES(idx).type;
 
-               DEBUG ("%s: Checking handle %p", __func__, handle);
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Checking handle %p", __func__, handle);
 
                if(((_wapi_handle_test_capabilities (handle, WAPI_HANDLE_CAP_OWN)==TRUE) &&
                    (_wapi_handle_ops_isowned (handle) == TRUE)) ||
@@ -1455,7 +1428,7 @@ again:
                    _WAPI_PRIVATE_HANDLES(idx).signalled == TRUE)) {
                        count++;
                        
-                       DEBUG ("%s: Handle %p signalled", __func__,
+                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Handle %p signalled", __func__,
                                   handle);
                        if(*lowest>i) {
                                *lowest=i;
@@ -1463,7 +1436,7 @@ again:
                }
        }
        
-       DEBUG ("%s: %d event handles signalled", __func__, count);
+       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: %d event handles signalled", __func__, count);
 
        if ((waitall == TRUE && count == numhandles) ||
            (waitall == FALSE && count > 0)) {
@@ -1472,7 +1445,7 @@ again:
                ret=FALSE;
        }
        
-       DEBUG ("%s: Returning %d", __func__, ret);
+       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Returning %d", __func__, ret);
 
        *retcount=count;
        
@@ -1490,87 +1463,62 @@ void _wapi_handle_unlock_handles (guint32 numhandles, gpointer *handles)
        for(i=0; i<numhandles; i++) {
                gpointer handle = handles[i];
                
-               DEBUG ("%s: unlocking handle %p", __func__, handle);
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking handle %p", __func__, handle);
 
                thr_ret = _wapi_handle_unlock_handle (handle);
                g_assert (thr_ret == 0);
        }
 }
 
-static int timedwait_signal_poll_cond (pthread_cond_t *cond, mono_mutex_t *mutex, struct timespec *timeout, gboolean alertable)
+int
+_wapi_handle_timedwait_signal (guint32 timeout, gboolean poll, gboolean *alerted)
 {
-       struct timespec fake_timeout;
-       int ret;
-
-       if (!alertable) {
-               /*
-                * pthread_cond_(timed)wait() can return 0 even if the condition was not
-                * signalled.  This happens at least on Darwin.  We surface this, i.e., we
-                * get spurious wake-ups.
-                *
-                * http://pubs.opengroup.org/onlinepubs/007908775/xsh/pthread_cond_wait.html
-                */
-               if (timeout)
-                       ret=mono_cond_timedwait (cond, mutex, timeout);
-               else
-                       ret=mono_cond_wait (cond, mutex);
-       } else {
-               _wapi_calc_timeout (&fake_timeout, 100);
-       
-               if (timeout != NULL && ((fake_timeout.tv_sec > timeout->tv_sec) ||
-                                                               (fake_timeout.tv_sec == timeout->tv_sec &&
-                                                                fake_timeout.tv_nsec > timeout->tv_nsec))) {
-                       /* Real timeout is less than 100ms time */
-                       ret=mono_cond_timedwait (cond, mutex, timeout);
-               } else {
-                       ret=mono_cond_timedwait (cond, mutex, &fake_timeout);
-
-                       /* Mask the fake timeout, this will cause
-                        * another poll if the cond was not really signaled
-                        */
-                       if (ret==ETIMEDOUT) {
-                               ret=0;
-                       }
-               }
-       }
-       
-       return(ret);
+       return _wapi_handle_timedwait_signal_handle (_wapi_global_signal_handle, timeout, TRUE, poll, alerted);
 }
 
-int _wapi_handle_wait_signal (gboolean poll)
+static void
+signal_handle_and_unref (gpointer handle)
 {
-       return _wapi_handle_timedwait_signal_handle (_wapi_global_signal_handle, NULL, TRUE, poll);
-}
+       pthread_cond_t *cond;
+       mono_mutex_t *mutex;
+       guint32 idx;
 
-int _wapi_handle_timedwait_signal (struct timespec *timeout, gboolean poll)
-{
-       return _wapi_handle_timedwait_signal_handle (_wapi_global_signal_handle, timeout, TRUE, poll);
-}
+       g_assert (handle);
 
-int _wapi_handle_wait_signal_handle (gpointer handle, gboolean alertable)
-{
-       DEBUG ("%s: waiting for %p", __func__, handle);
-       
-       return _wapi_handle_timedwait_signal_handle (handle, NULL, alertable, FALSE);
+       /* If we reach here, then interrupt token is set to the flag value, which
+        * means that the target thread is either
+        * - before the first CAS in timedwait, which means it won't enter the wait.
+        * - it is after the first CAS, so it is already waiting, or it will enter
+        *    the wait, and it will be interrupted by the broadcast. */
+       idx = GPOINTER_TO_UINT (handle);
+       cond = &_WAPI_PRIVATE_HANDLES (idx).signal_cond;
+       mutex = &_WAPI_PRIVATE_HANDLES (idx).signal_mutex;
+
+       mono_os_mutex_lock (mutex);
+       mono_os_cond_broadcast (cond);
+       mono_os_mutex_unlock (mutex);
+
+       _wapi_handle_unref (handle);
 }
 
-int _wapi_handle_timedwait_signal_handle (gpointer handle,
-                                                                                 struct timespec *timeout, gboolean alertable, gboolean poll)
+int
+_wapi_handle_timedwait_signal_handle (gpointer handle, guint32 timeout, gboolean alertable, gboolean poll, gboolean *alerted)
 {
-       DEBUG ("%s: waiting for %p (type %s)", __func__, handle,
+       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: waiting for %p (type %s)", __func__, handle,
                   _wapi_handle_typename[_wapi_handle_type (handle)]);
-       
+
+       if (alertable)
+               g_assert (alerted);
+
+       if (alerted)
+               *alerted = FALSE;
+
        if (_WAPI_SHARED_HANDLE (_wapi_handle_type (handle))) {
                if (WAPI_SHARED_HANDLE_DATA(handle).signalled == TRUE) {
                        return (0);
                }
-               if (timeout != NULL) {
-                       struct timespec fake_timeout;
-                       _wapi_calc_timeout (&fake_timeout, 100);
-               
-                       if ((fake_timeout.tv_sec > timeout->tv_sec) ||
-                               (fake_timeout.tv_sec == timeout->tv_sec &&
-                                fake_timeout.tv_nsec > timeout->tv_nsec)) {
+               if (timeout != INFINITE) {
+                       if (timeout < 100) {
                                /* FIXME: Real timeout is less than
                                 * 100ms time, but is it really worth
                                 * calculating to the exact ms?
@@ -1593,24 +1541,52 @@ int _wapi_handle_timedwait_signal_handle (gpointer handle,
                pthread_cond_t *cond;
                mono_mutex_t *mutex;
 
-               if (alertable && !wapi_thread_set_wait_handle (handle))
-                       return 0;
+               if (alertable) {
+                       mono_thread_info_install_interrupt (signal_handle_and_unref, handle, alerted);
+                       if (*alerted)
+                               return 0;
+                       _wapi_handle_ref (handle);
+               }
 
                cond = &_WAPI_PRIVATE_HANDLES (idx).signal_cond;
                mutex = &_WAPI_PRIVATE_HANDLES (idx).signal_mutex;
 
-               if (poll) {
-                       /* This is needed when waiting for process handles */
-                       res = timedwait_signal_poll_cond (cond, mutex, timeout, alertable);
+               if (!poll) {
+                       res = mono_os_cond_timedwait (cond, mutex, timeout);
                } else {
-                       if (timeout)
-                               res = mono_cond_timedwait (cond, mutex, timeout);
-                       else
-                               res = mono_cond_wait (cond, mutex);
+                       /* This is needed when waiting for process handles */
+                       if (!alertable) {
+                               /*
+                                * pthread_cond_(timed)wait() can return 0 even if the condition was not
+                                * signalled.  This happens at least on Darwin.  We surface this, i.e., we
+                                * get spurious wake-ups.
+                                *
+                                * http://pubs.opengroup.org/onlinepubs/007908775/xsh/pthread_cond_wait.html
+                                */
+                               res = mono_os_cond_timedwait (cond, mutex, timeout);
+                       } else {
+                               if (timeout < 100) {
+                                       /* Real timeout is less than 100ms time */
+                                       res = mono_os_cond_timedwait (cond, mutex, timeout);
+                               } else {
+                                       res = mono_os_cond_timedwait (cond, mutex, 100);
+
+                                       /* Mask the fake timeout, this will cause
+                                        * another poll if the cond was not really signaled
+                                        */
+                                       if (res == ETIMEDOUT)
+                                               res = 0;
+                               }
+                       }
                }
 
-               if (alertable)
-                       wapi_thread_clear_wait_handle (handle);
+               if (alertable) {
+                       mono_thread_info_uninstall_interrupt (alerted);
+                       if (!*alerted) {
+                               /* if it is alerted, then the handle is unref in the interrupt callback */
+                               _wapi_handle_unref (handle);
+                       }
+               }
 
                return res;
        }
@@ -1619,21 +1595,17 @@ int _wapi_handle_timedwait_signal_handle (gpointer handle,
 void
 _wapi_free_share_info (_WapiFileShare *share_info)
 {
-       if (!_wapi_shm_enabled ()) {
-               file_share_hash_lock ();
-               g_hash_table_remove (file_share_hash, share_info);
-               file_share_hash_unlock ();
-               /* The hashtable dtor frees share_info */
-       } else {
-               memset (share_info, '\0', sizeof(struct _WapiFileShare));
-       }
+       file_share_hash_lock ();
+       g_hash_table_remove (file_share_hash, share_info);
+       file_share_hash_unlock ();
+       /* The hashtable dtor frees share_info */
 }
 
 static gint
 wapi_share_info_equal (gconstpointer ka, gconstpointer kb)
 {
-       const _WapiFileShare *s1 = ka;
-       const _WapiFileShare *s2 = kb;
+       const _WapiFileShare *s1 = (const _WapiFileShare *)ka;
+       const _WapiFileShare *s2 = (const _WapiFileShare *)kb;
 
        return (s1->device == s2->device && s1->inode == s2->inode) ? 1 : 0;
 }
@@ -1641,7 +1613,7 @@ wapi_share_info_equal (gconstpointer ka, gconstpointer kb)
 static guint
 wapi_share_info_hash (gconstpointer data)
 {
-       const _WapiFileShare *s = data;
+       const _WapiFileShare *s = (const _WapiFileShare *)data;
 
        return s->inode;
 }
@@ -1654,8 +1626,7 @@ gboolean _wapi_handle_get_or_set_share (guint64 device, guint64 inode,
                                        struct _WapiFileShare **share_info)
 {
        struct _WapiFileShare *file_share;
-       guint32 now = (guint32)(time(NULL) & 0xFFFFFFFF);
-       int thr_ret, i, first_unused = -1;
+       int thr_ret;
        gboolean exists = FALSE;
 
        /* Prevents entries from expiring under us as we search
@@ -1667,110 +1638,46 @@ gboolean _wapi_handle_get_or_set_share (guint64 device, guint64 inode,
        thr_ret = _wapi_shm_sem_lock (_WAPI_SHARED_SEM_FILESHARE);
        g_assert (thr_ret == 0);
 
-       if (!_wapi_shm_enabled ()) {
-               _WapiFileShare tmp;
-
-               /*
-                * Instead of allocating a 4MB array, we use a hash table to keep track of this
-                * info. This is needed even if SHM is disabled, to track sharing inside
-                * the current process.
-                */
-               if (!file_share_hash) {
-                       file_share_hash = g_hash_table_new_full (wapi_share_info_hash, wapi_share_info_equal, NULL, g_free);
-                       mono_mutex_init_recursive (&file_share_hash_mutex);
-               }
-                       
-               tmp.device = device;
-               tmp.inode = inode;
+       _WapiFileShare tmp;
 
-               file_share_hash_lock ();
+       /*
+        * Instead of allocating a 4MB array, we use a hash table to keep track of this
+        * info. This is needed even if SHM is disabled, to track sharing inside
+        * the current process.
+        */
+       if (!file_share_hash) {
+               file_share_hash = g_hash_table_new_full (wapi_share_info_hash, wapi_share_info_equal, NULL, g_free);
+               mono_os_mutex_init_recursive (&file_share_hash_mutex);
+       }
 
-               file_share = g_hash_table_lookup (file_share_hash, &tmp);
-               if (file_share) {
-                       *old_sharemode = file_share->sharemode;
-                       *old_access = file_share->access;
-                       *share_info = file_share;
-                       
-                       InterlockedIncrement ((gint32 *)&file_share->handle_refs);
-                       exists = TRUE;
-               } else {
-                       file_share = g_new0 (_WapiFileShare, 1);
+       tmp.device = device;
+       tmp.inode = inode;
 
-                       file_share->device = device;
-                       file_share->inode = inode;
-                       file_share->opened_by_pid = _wapi_getpid ();
-                       file_share->sharemode = new_sharemode;
-                       file_share->access = new_access;
-                       file_share->handle_refs = 1;
-                       *share_info = file_share;
+       file_share_hash_lock ();
 
-                       g_hash_table_insert (file_share_hash, file_share, file_share);
-               }
+       file_share = (_WapiFileShare *)g_hash_table_lookup (file_share_hash, &tmp);
+       if (file_share) {
+               *old_sharemode = file_share->sharemode;
+               *old_access = file_share->access;
+               *share_info = file_share;
 
-               file_share_hash_unlock ();
+               InterlockedIncrement ((gint32 *)&file_share->handle_refs);
+               exists = TRUE;
        } else {
-               /* If a linear scan gets too slow we'll have to fit a hash
-                * table onto the shared mem backing store
-                */
-               *share_info = NULL;
-               for (i = 0; i <= _wapi_fileshare_layout->hwm; i++) {
-                       file_share = &_wapi_fileshare_layout->share_info[i];
+               file_share = g_new0 (_WapiFileShare, 1);
 
-                       /* Make a note of an unused slot, in case we need to
-                        * store share info
-                        */
-                       if (first_unused == -1 && file_share->handle_refs == 0) {
-                               first_unused = i;
-                               continue;
-                       }
-               
-                       if (file_share->handle_refs == 0) {
-                               continue;
-                       }
-               
-                       if (file_share->device == device &&
-                               file_share->inode == inode) {
-                               *old_sharemode = file_share->sharemode;
-                               *old_access = file_share->access;
-                               *share_info = file_share;
-                       
-                               /* Increment the reference count while we
-                                * still have sole access to the shared area.
-                                * This makes the increment atomic wrt
-                                * collections
-                                */
-                               InterlockedIncrement ((gint32 *)&file_share->handle_refs);
-                       
-                               exists = TRUE;
-                               break;
-                       }
-               }
-       
-               if (!exists) {
-                       if (i == _WAPI_FILESHARE_SIZE && first_unused == -1) {
-                               /* No more space */
-                       } else {
-                               if (first_unused == -1) {
-                                       file_share = &_wapi_fileshare_layout->share_info[++i];
-                                       _wapi_fileshare_layout->hwm = i;
-                               } else {
-                                       file_share = &_wapi_fileshare_layout->share_info[first_unused];
-                               }
-                       
-                               file_share->device = device;
-                               file_share->inode = inode;
-                               file_share->opened_by_pid = _wapi_getpid ();
-                               file_share->sharemode = new_sharemode;
-                               file_share->access = new_access;
-                               file_share->handle_refs = 1;
-                               *share_info = file_share;
-                       }
-               }
+               file_share->device = device;
+               file_share->inode = inode;
+               file_share->opened_by_pid = _wapi_getpid ();
+               file_share->sharemode = new_sharemode;
+               file_share->access = new_access;
+               file_share->handle_refs = 1;
+               *share_info = file_share;
 
-               if (*share_info != NULL) {
-                       InterlockedExchange ((gint32 *)&(*share_info)->timestamp, now);
-               }
+               g_hash_table_insert (file_share_hash, file_share, file_share);
        }
+
+       file_share_hash_unlock ();
        
        thr_ret = _wapi_shm_sem_unlock (_WAPI_SHARED_SEM_FILESHARE);
 
@@ -1787,7 +1694,7 @@ static void _wapi_handle_check_share_by_pid (struct _WapiFileShare *share_info)
 {
 #if defined(__native_client__)
        g_assert_not_reached ();
-#else
+#elif defined(HAVE_KILL)
        if (kill (share_info->opened_by_pid, 0) == -1 &&
            (errno == ESRCH ||
             errno == EPERM)) {
@@ -1795,7 +1702,7 @@ static void _wapi_handle_check_share_by_pid (struct _WapiFileShare *share_info)
                 * owned by someone else) so mark this share info as
                 * dead
                 */
-               DEBUG ("%s: Didn't find it, destroying entry", __func__);
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Didn't find it, destroying entry", __func__);
 
                _wapi_free_share_info (share_info);
        }
@@ -1844,7 +1751,7 @@ void _wapi_handle_check_share (struct _WapiFileShare *share_info, int fd)
                                struct _WapiHandle_file *file_handle = &handle->u.file;
 
                                if (file_handle->share_info == share_info) {
-                                       DEBUG ("%s: handle 0x%x has this file open!",
+                                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle 0x%x has this file open!",
                                                           __func__, i);
 
                                        goto done;
@@ -1857,7 +1764,7 @@ void _wapi_handle_check_share (struct _WapiFileShare *share_info, int fd)
                _wapi_handle_check_share_by_pid (share_info);
        } else if (found == FALSE) {
                /* Blank out this entry, as it is stale */
-               DEBUG ("%s: Didn't find it, destroying entry", __func__);
+               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Didn't find it, destroying entry", __func__);
 
                _wapi_free_share_info (share_info);
        }
@@ -1897,7 +1804,7 @@ void _wapi_handle_dump (void)
        guint32 i, k;
        int thr_ret;
        
-       thr_ret = mono_mutex_lock (&scan_mutex);
+       thr_ret = mono_os_mutex_lock (&scan_mutex);
        g_assert (thr_ret == 0);
        
        for(i = SLOT_INDEX (0); i < _wapi_private_handle_slot_count; i++) {
@@ -1914,13 +1821,14 @@ void _wapi_handle_dump (void)
                                                 _wapi_handle_typename[handle_data->type],
                                                 handle_data->signalled?"Sg":"Un",
                                                 handle_data->ref);
-                               handle_details[handle_data->type](&handle_data->u);
+                               if (handle_details[handle_data->type])
+                                       handle_details[handle_data->type](&handle_data->u);
                                g_print ("\n");
                        }
                }
        }
 
-       thr_ret = mono_mutex_unlock (&scan_mutex);
+       thr_ret = mono_os_mutex_unlock (&scan_mutex);
        g_assert (thr_ret == 0);
 }
 
@@ -1930,57 +1838,3 @@ static void _wapi_shared_details (gpointer handle_info)
        
        g_print ("offset: 0x%x", shared->offset);
 }
-
-void _wapi_handle_update_refs (void)
-{
-       guint32 i, k;
-       int thr_ret;
-       guint32 now = (guint32)(time (NULL) & 0xFFFFFFFF);
-       
-       thr_ret = _wapi_handle_lock_shared_handles ();
-       g_assert (thr_ret == 0);
-
-       /* Prevent file share entries racing with us */
-       thr_ret = _wapi_shm_sem_lock (_WAPI_SHARED_SEM_FILESHARE);
-       g_assert(thr_ret == 0);
-
-       thr_ret = mono_mutex_lock (&scan_mutex);
-       
-       for(i = SLOT_INDEX (0); i < _wapi_private_handle_slot_count; i++) {
-               if (_wapi_private_handles [i]) {
-                       for (k = SLOT_OFFSET (0); k < _WAPI_HANDLE_INITIAL_COUNT; k++) {
-                               struct _WapiHandleUnshared *handle = &_wapi_private_handles [i][k];
-
-                               if (_WAPI_SHARED_HANDLE(handle->type)) {
-                                       struct _WapiHandleShared *shared_data;
-                               
-                                       DEBUG ("%s: (%d) handle 0x%x is SHARED (%s)", __func__, _wapi_getpid (), i * _WAPI_HANDLE_INITIAL_COUNT + k, _wapi_handle_typename[handle->type]);
-
-                                       shared_data = &_wapi_shared_layout->handles[handle->u.shared.offset];
-
-                                       DEBUG ("%s: (%d) Updating timestamp of handle 0x%x", __func__, _wapi_getpid (), handle->u.shared.offset);
-
-                                       InterlockedExchange ((gint32 *)&shared_data->timestamp, now);
-                               } else if (handle->type == WAPI_HANDLE_FILE) {
-                                       struct _WapiHandle_file *file_handle = &handle->u.file;
-                               
-                                       DEBUG ("%s: (%d) handle 0x%x is FILE", __func__, _wapi_getpid (), i * _WAPI_HANDLE_INITIAL_COUNT + k);
-                               
-                                       g_assert (file_handle->share_info != NULL);
-
-                                       DEBUG ("%s: (%d) Inc refs on fileshare 0x%x", __func__, _wapi_getpid (), (file_handle->share_info - &_wapi_fileshare_layout->share_info[0]) / sizeof(struct _WapiFileShare));
-
-                                       InterlockedExchange ((gint32 *)&file_handle->share_info->timestamp, now);
-                               }
-                       }
-               }
-       }
-
-       thr_ret = mono_mutex_unlock (&scan_mutex);
-       g_assert (thr_ret == 0);
-       
-       thr_ret = _wapi_shm_sem_unlock (_WAPI_SHARED_SEM_FILESHARE);
-
-       _wapi_handle_unlock_shared_handles ();
-}
-