[runtime] Move more thread attach code to mono-threads from io-layer.
[mono.git] / mono / io-layer / handles.c
index 97be0c71b9c771e5ba3cb20e8b8fa45f9e2fee3c..ea9cbeccbc138f262c8b23a4fc25fd1889ebebb7 100644 (file)
@@ -4,7 +4,8 @@
  * Author:
  *     Dick Porter (dick@ximian.com)
  *
- * (C) 2002-2006 Novell, Inc.
+ * (C) 2002-2011 Novell, Inc.
+ * Copyright 2011 Xamarin Inc
  */
 
 #include <config.h>
@@ -12,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
 #include <mono/io-layer/wapi.h>
 #include <mono/io-layer/wapi-private.h>
 #include <mono/io-layer/handles-private.h>
-#include <mono/io-layer/mono-mutex.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/critical-section-private.h>
 
-#undef DEBUG
+#include <mono/utils/mono-mutex.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};
@@ -152,7 +159,7 @@ gboolean _wapi_has_shut_down = FALSE;
 static pid_t _wapi_pid;
 static mono_once_t pid_init_once = MONO_ONCE_INIT;
 
-static gpointer _wapi_handle_real_new (WapiHandleType type, gpointer handle_specific);
+static void _wapi_handle_unref_full (gpointer handle, gboolean ignore_private_busy_handles);
 
 static void pid_init (void)
 {
@@ -167,14 +174,12 @@ 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)
 {
        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
@@ -185,34 +190,12 @@ 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.
-                                        */
-                                       _wapi_thread_set_termination_details (handle, 0);
-                               }
-                       }
-                               
+
                        for(k = handle_data->ref; k > 0; k--) {
-#ifdef DEBUG
-                               g_message ("%s: unreffing %s handle %p", __func__, _wapi_handle_typename[type], handle);
-#endif
+                               DEBUG ("%s: unreffing %s handle %p", __func__, _wapi_handle_typename[type], handle);
                                        
-                               _wapi_handle_unref (handle);
+                               _wapi_handle_unref_full (handle, TRUE);
                        }
                }
        }
@@ -231,19 +214,13 @@ static void handle_cleanup (void)
                g_free (_wapi_private_handles [i]);
 }
 
-void _wapi_cleanup ()
-{
-       g_assert (_wapi_has_shut_down == FALSE);
-       
-       _wapi_has_shut_down = TRUE;
-
-       _wapi_critical_section_cleanup ();
-       _wapi_error_cleanup ();
-       _wapi_thread_cleanup ();
-}
-
-static mono_once_t shared_init_once = MONO_ONCE_INIT;
-static void shared_init (void)
+/*
+ * wapi_init:
+ *
+ *   Initialize the io-layer.
+ */
+void
+wapi_init (void)
 {
        g_assert ((sizeof (handle_ops) / sizeof (handle_ops[0]))
                  == WAPI_HANDLE_COUNT);
@@ -282,13 +259,15 @@ static void shared_init (void)
        if (_wapi_shm_enabled ())
                _wapi_collection_init ();
 #endif
+       _wapi_io_init ();
+       mono_mutex_init (&scan_mutex);
 
-       /* Can't call wapi_handle_new as it calls us recursively */
-       _wapi_global_signal_handle = _wapi_handle_real_new (WAPI_HANDLE_EVENT, NULL);
+       _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
@@ -297,6 +276,17 @@ static void shared_init (void)
        g_atexit (handle_cleanup);
 }
 
+void
+wapi_cleanup (void)
+{
+       g_assert (_wapi_has_shut_down == FALSE);
+       
+       _wapi_has_shut_down = TRUE;
+
+       _wapi_error_cleanup ();
+       _wapi_thread_cleanup ();
+}
+
 static void _wapi_handle_init_shared (struct _WapiHandleShared *handle,
                                      WapiHandleType type,
                                      gpointer handle_specific)
@@ -328,7 +318,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, NULL);
+               thr_ret = mono_mutex_init (&handle->signal_mutex);
                g_assert (thr_ret == 0);
 
                if (handle_specific != NULL) {
@@ -445,16 +435,17 @@ again:
        return(0);
 }
 
-static gpointer _wapi_handle_real_new (WapiHandleType type, gpointer handle_specific)
+gpointer 
+_wapi_handle_new (WapiHandleType type, gpointer handle_specific)
 {
        guint32 handle_idx = 0;
        gpointer handle;
        int thr_ret;
-       
-#ifdef DEBUG
-       g_message ("%s: Creating new handle of type %s", __func__,
+
+       g_assert (_wapi_has_shut_down == FALSE);
+               
+       DEBUG ("%s: Creating new handle of type %s", __func__,
                   _wapi_handle_typename[type]);
-#endif
 
        g_assert(!_WAPI_FD_HANDLE(type));
        
@@ -492,9 +483,7 @@ static gpointer _wapi_handle_real_new (WapiHandleType type, gpointer handle_spec
        
        handle = GUINT_TO_POINTER (handle_idx);
 
-#ifdef DEBUG
-       g_message ("%s: Allocated new handle %p", __func__, handle);
-#endif
+       DEBUG ("%s: Allocated new handle %p", __func__, handle);
        
        if (_WAPI_SHARED_HANDLE(type)) {
                /* Add the shared section too */
@@ -503,7 +492,6 @@ static gpointer _wapi_handle_real_new (WapiHandleType type, gpointer handle_spec
                ref = _wapi_handle_new_shared (type, handle_specific);
                if (ref == 0) {
                        _wapi_handle_collect ();
-                       _wapi_process_reap ();
                        ref = _wapi_handle_new_shared (type, handle_specific);
                        if (ref == 0) {
                                /* FIXME: grow the arrays */
@@ -513,25 +501,14 @@ static gpointer _wapi_handle_real_new (WapiHandleType type, gpointer handle_spec
                }
                
                _WAPI_PRIVATE_HANDLES(handle_idx).u.shared.offset = ref;
-#ifdef DEBUG
-               g_message ("%s: New shared handle at offset 0x%x", __func__,
+               DEBUG ("%s: New shared handle at offset 0x%x", __func__,
                           ref);
-#endif
        }
                
 done:
        return(handle);
 }
 
-gpointer _wapi_handle_new (WapiHandleType type, gpointer handle_specific)
-{
-       g_assert (_wapi_has_shut_down == FALSE);
-       
-       mono_once (&shared_init_once, shared_init);
-
-       return _wapi_handle_real_new (type, handle_specific);
-}
-
 gpointer _wapi_handle_new_from_offset (WapiHandleType type, guint32 offset,
                                       gboolean timestamp)
 {
@@ -542,12 +519,8 @@ gpointer _wapi_handle_new_from_offset (WapiHandleType type, guint32 offset,
        
        g_assert (_wapi_has_shut_down == FALSE);
        
-       mono_once (&shared_init_once, shared_init);
-
-#ifdef DEBUG
-       g_message ("%s: Creating new handle of type %s to offset %d", __func__,
+       DEBUG ("%s: Creating new handle of type %s to offset %d", __func__,
                   _wapi_handle_typename[type], offset);
-#endif
 
        g_assert(!_WAPI_FD_HANDLE(type));
        g_assert(_WAPI_SHARED_HANDLE(type));
@@ -587,10 +560,8 @@ first_pass_done:
        if (handle != INVALID_HANDLE_VALUE) {
                _wapi_handle_ref (handle);
 
-#ifdef DEBUG
-               g_message ("%s: Returning old handle %p referencing 0x%x",
+               DEBUG ("%s: Returning old handle %p referencing 0x%x",
                           __func__, handle, offset);
-#endif
                return (handle);
        }
 
@@ -600,19 +571,15 @@ first_pass_done:
        
        if (shared->type == WAPI_HANDLE_UNUSED) {
                /* Someone deleted this handle while we were working */
-#ifdef DEBUG
-               g_message ("%s: Handle at 0x%x unused", __func__, offset);
-#endif
+               DEBUG ("%s: Handle at 0x%x unused", __func__, offset);
                goto done;
        }
 
        if (shared->type != type) {
-#ifdef DEBUG
-               g_message ("%s: Wrong type at %d 0x%x! Found %s wanted %s",
+               DEBUG ("%s: Wrong type at %d 0x%x! Found %s wanted %s",
                           __func__, offset, offset,
                           _wapi_handle_typename[shared->type],
                           _wapi_handle_typename[type]);
-#endif
                goto done;
        }
        
@@ -643,9 +610,7 @@ first_pass_done:
        _WAPI_PRIVATE_HANDLES(handle_idx).u.shared.offset = offset;
        InterlockedIncrement ((gint32 *)&shared->handle_refs);
        
-#ifdef DEBUG
-       g_message ("%s: Allocated new handle %p referencing 0x%x (shared refs %d)", __func__, handle, offset, shared->handle_refs);
-#endif
+       DEBUG ("%s: Allocated new handle %p referencing 0x%x (shared refs %d)", __func__, handle, offset, shared->handle_refs);
        
 done:
        _wapi_handle_unlock_shared_handles ();
@@ -682,20 +647,14 @@ gpointer _wapi_handle_new_fd (WapiHandleType type, int fd,
        
        g_assert (_wapi_has_shut_down == FALSE);
        
-       mono_once (&shared_init_once, shared_init);
-       
-#ifdef DEBUG
-       g_message ("%s: Creating new handle of type %s", __func__,
+       DEBUG ("%s: Creating new handle of type %s", __func__,
                   _wapi_handle_typename[type]);
-#endif
        
        g_assert(_WAPI_FD_HANDLE(type));
        g_assert(!_WAPI_SHARED_HANDLE(type));
        
        if (fd >= _wapi_fd_reserve) {
-#ifdef DEBUG
-               g_message ("%s: fd %d is too big", __func__, fd);
-#endif
+               DEBUG ("%s: fd %d is too big", __func__, fd);
 
                return(GUINT_TO_POINTER (_WAPI_HANDLE_INVALID));
        }
@@ -707,17 +666,13 @@ gpointer _wapi_handle_new_fd (WapiHandleType type, int fd,
        handle = &_WAPI_PRIVATE_HANDLES(fd);
        
        if (handle->type != WAPI_HANDLE_UNUSED) {
-#ifdef DEBUG
-               g_message ("%s: fd %d is already in use!", __func__, fd);
-#endif
+               DEBUG ("%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
                 */
        }
 
-#ifdef DEBUG
-       g_message ("%s: Assigning new fd handle %d", __func__, fd);
-#endif
+       DEBUG ("%s: Assigning new fd handle %d", __func__, fd);
 
        /* Prevent file share entries racing with us, when the file
         * handle is only half initialised
@@ -817,6 +772,7 @@ _wapi_handle_foreach (WapiHandleType type,
  * unreffed if the check function returns FALSE, so callers must not
  * rely on the handle persisting (unless the check function returns
  * TRUE)
+ * The caller owns the returned handle.
  */
 gpointer _wapi_search_handle (WapiHandleType type,
                              gboolean (*check)(gpointer test, gpointer user),
@@ -864,9 +820,7 @@ gpointer _wapi_search_handle (WapiHandleType type,
 
        if (!found && search_shared && _WAPI_SHARED_HANDLE (type)) {
                /* Not found yet, so search the shared memory too */
-#ifdef DEBUG
-               g_message ("%s: Looking at other shared handles...", __func__);
-#endif
+               DEBUG ("%s: Looking at other shared handles...", __func__);
 
                for (i = 0; i < _WAPI_HANDLE_INITIAL_COUNT; i++) {
                        shared = &_wapi_shared_layout->handles[i];
@@ -887,9 +841,7 @@ gpointer _wapi_search_handle (WapiHandleType type,
                                        continue;
                                }
                                
-#ifdef DEBUG
-                               g_message ("%s: Opened tmp handle %p (type %s) from offset %d", __func__, ret, _wapi_handle_typename[type], i);
-#endif
+                               DEBUG ("%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
@@ -966,10 +918,8 @@ gint32 _wapi_search_handle_namespace (WapiHandleType type,
        
        g_assert(_WAPI_SHARED_HANDLE(type));
        
-#ifdef DEBUG
-       g_message ("%s: Lookup for handle named [%s] type %s", __func__,
+       DEBUG ("%s: Lookup for handle named [%s] type %s", __func__,
                   utf8_name, _wapi_handle_typename[type]);
-#endif
 
        /* Do a handle collection before starting to look, so that any
         * stale cruft gets removed
@@ -992,28 +942,20 @@ gint32 _wapi_search_handle_namespace (WapiHandleType type,
                        continue;
                }
 
-#ifdef DEBUG
-               g_message ("%s: found a shared namespace handle at 0x%x (type %s)", __func__, i, _wapi_handle_typename[shared_handle_data->type]);
-#endif
+               DEBUG ("%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;
                        
-#ifdef DEBUG
-               g_message ("%s: name is [%s]", __func__, sharedns->name);
-#endif
+               DEBUG ("%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 */
-#ifdef DEBUG
-                               g_message ("%s: handle 0x%x matches name but is wrong type: %s", __func__, i, _wapi_handle_typename[shared_handle_data->type]);
-#endif
+                               DEBUG ("%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 {
-#ifdef DEBUG
-                               g_message ("%s: handle 0x%x matches name and type", __func__, i);
-#endif
+                               DEBUG ("%s: handle 0x%x matches name and type", __func__, i);
                                ret = i;
                                goto done;
                        }
@@ -1065,10 +1007,10 @@ void _wapi_handle_ref (gpointer handle)
 }
 
 /* The handle must not be locked on entry to this function */
-void _wapi_handle_unref (gpointer handle)
+static void _wapi_handle_unref_full (gpointer handle, gboolean ignore_private_busy_handles)
 {
        guint32 idx = GPOINTER_TO_UINT(handle);
-       gboolean destroy = FALSE;
+       gboolean destroy = FALSE, early_exit = FALSE;
        int thr_ret;
 
        if (!_WAPI_PRIVATE_VALID_SLOT (idx)) {
@@ -1120,9 +1062,7 @@ void _wapi_handle_unref (gpointer handle)
                pthread_cleanup_push ((void(*)(void *))mono_mutex_unlock_in_cleanup, (void *)&scan_mutex);
                thr_ret = mono_mutex_lock (&scan_mutex);
 
-#ifdef DEBUG
-               g_message ("%s: Destroying handle %p", __func__, handle);
-#endif
+               DEBUG ("%s: Destroying handle %p", __func__, handle);
                
                memcpy (&handle_data, &_WAPI_PRIVATE_HANDLES(idx),
                        sizeof (struct _WapiHandleUnshared));
@@ -1139,10 +1079,19 @@ void _wapi_handle_unref (gpointer handle)
                         * "unlock_and_destroy" atomic function.
                         */
                        thr_ret = mono_mutex_destroy (&_WAPI_PRIVATE_HANDLES(idx).signal_mutex);
-                       g_assert (thr_ret == 0);
-                               
-                       thr_ret = pthread_cond_destroy (&_WAPI_PRIVATE_HANDLES(idx).signal_cond);
-                       g_assert (thr_ret == 0);
+                       /*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;
+                       } else {
+                               if (thr_ret != 0)
+                                       g_error ("Error destroying handle %p mutex due to %d\n", handle, thr_ret);
+
+                               thr_ret = pthread_cond_destroy (&_WAPI_PRIVATE_HANDLES(idx).signal_cond);
+                               if (thr_ret == EBUSY && ignore_private_busy_handles)
+                                       early_exit = TRUE;
+                               else if (thr_ret != 0)
+                                       g_error ("Error destroying handle %p cond var due to %d\n", handle, thr_ret);
+                       }
                } else {
                        struct _WapiHandleShared *shared = &_wapi_shared_layout->handles[handle_data.u.shared.offset];
 
@@ -1168,6 +1117,8 @@ void _wapi_handle_unref (gpointer handle)
                g_assert (thr_ret == 0);
                pthread_cleanup_pop (0);
 
+               if (early_exit)
+                       return;
                if (is_shared) {
                        _wapi_handle_unlock_shared_handles ();
                }
@@ -1182,6 +1133,11 @@ void _wapi_handle_unref (gpointer handle)
        }
 }
 
+void _wapi_handle_unref (gpointer handle)
+{
+       _wapi_handle_unref_full (handle, FALSE);
+}
+
 void _wapi_handle_register_capabilities (WapiHandleType type,
                                         WapiHandleCapability caps)
 {
@@ -1200,10 +1156,8 @@ gboolean _wapi_handle_test_capabilities (gpointer handle,
        
        type = _WAPI_PRIVATE_HANDLES(idx).type;
 
-#ifdef DEBUG
-       g_message ("%s: testing 0x%x against 0x%x (%d)", __func__,
+       DEBUG ("%s: testing 0x%x against 0x%x (%d)", __func__,
                   handle_caps[type], caps, handle_caps[type] & caps);
-#endif
        
        return((handle_caps[type] & caps) != 0);
 }
@@ -1287,7 +1241,7 @@ gboolean _wapi_handle_ops_isowned (gpointer handle)
        }
 }
 
-guint32 _wapi_handle_ops_special_wait (gpointer handle, guint32 timeout)
+guint32 _wapi_handle_ops_special_wait (gpointer handle, guint32 timeout, gboolean alertable)
 {
        guint32 idx = GPOINTER_TO_UINT(handle);
        WapiHandleType type;
@@ -1300,7 +1254,7 @@ guint32 _wapi_handle_ops_special_wait (gpointer handle, guint32 timeout)
        
        if (handle_ops[type] != NULL &&
            handle_ops[type]->special_wait != NULL) {
-               return(handle_ops[type]->special_wait (handle, timeout));
+               return(handle_ops[type]->special_wait (handle, timeout, alertable));
        } else {
                return(WAIT_FAILED);
        }
@@ -1403,9 +1357,7 @@ again:
                gpointer handle = handles[i];
                guint32 idx = GPOINTER_TO_UINT(handle);
 
-#ifdef DEBUG
-               g_message ("%s: attempting to lock %p", __func__, handle);
-#endif
+               DEBUG ("%s: attempting to lock %p", __func__, handle);
 
                type = _WAPI_PRIVATE_HANDLES(idx).type;
 
@@ -1414,10 +1366,8 @@ again:
                if (thr_ret != 0) {
                        /* Bummer */
                        
-#ifdef DEBUG
-                       g_message ("%s: attempt failed for %p: %s", __func__,
+                       DEBUG ("%s: attempt failed for %p: %s", __func__,
                                   handle, strerror (thr_ret));
-#endif
 
                        thr_ret = _wapi_handle_unlock_shared_handles ();
                        g_assert (thr_ret == 0);
@@ -1441,19 +1391,15 @@ again:
                                iter=1;
                        }
                        
-#ifdef DEBUG
-                       g_message ("%s: Backing off for %d ms", __func__,
+                       DEBUG ("%s: Backing off for %d ms", __func__,
                                   iter*10);
-#endif
                        _wapi_handle_spin (10 * iter);
                        
                        goto again;
                }
        }
        
-#ifdef DEBUG
-       g_message ("%s: Locked all handles", __func__);
-#endif
+       DEBUG ("%s: Locked all handles", __func__);
 
        count=0;
        *lowest=numhandles;
@@ -1464,9 +1410,7 @@ again:
                
                type = _WAPI_PRIVATE_HANDLES(idx).type;
 
-#ifdef DEBUG
-               g_message ("%s: Checking handle %p", __func__, handle);
-#endif
+               DEBUG ("%s: Checking handle %p", __func__, handle);
 
                if(((_wapi_handle_test_capabilities (handle, WAPI_HANDLE_CAP_OWN)==TRUE) &&
                    (_wapi_handle_ops_isowned (handle) == TRUE)) ||
@@ -1476,19 +1420,15 @@ again:
                    _WAPI_PRIVATE_HANDLES(idx).signalled == TRUE)) {
                        count++;
                        
-#ifdef DEBUG
-                       g_message ("%s: Handle %p signalled", __func__,
+                       DEBUG ("%s: Handle %p signalled", __func__,
                                   handle);
-#endif
                        if(*lowest>i) {
                                *lowest=i;
                        }
                }
        }
        
-#ifdef DEBUG
-       g_message ("%s: %d event handles signalled", __func__, count);
-#endif
+       DEBUG ("%s: %d event handles signalled", __func__, count);
 
        if ((waitall == TRUE && count == numhandles) ||
            (waitall == FALSE && count > 0)) {
@@ -1497,9 +1437,7 @@ again:
                ret=FALSE;
        }
        
-#ifdef DEBUG
-       g_message ("%s: Returning %d", __func__, ret);
-#endif
+       DEBUG ("%s: Returning %d", __func__, ret);
 
        *retcount=count;
        
@@ -1517,9 +1455,7 @@ void _wapi_handle_unlock_handles (guint32 numhandles, gpointer *handles)
        for(i=0; i<numhandles; i++) {
                gpointer handle = handles[i];
                
-#ifdef DEBUG
-               g_message ("%s: unlocking handle %p", __func__, handle);
-#endif
+               DEBUG ("%s: unlocking handle %p", __func__, handle);
 
                thr_ret = _wapi_handle_unlock_handle (handle);
                g_assert (thr_ret == 0);
@@ -1571,9 +1507,7 @@ int _wapi_handle_timedwait_signal (struct timespec *timeout, gboolean poll)
 
 int _wapi_handle_wait_signal_handle (gpointer handle, gboolean alertable)
 {
-#ifdef DEBUG
-       g_message ("%s: waiting for %p", __func__, handle);
-#endif
+       DEBUG ("%s: waiting for %p", __func__, handle);
        
        return _wapi_handle_timedwait_signal_handle (handle, NULL, alertable, FALSE);
 }
@@ -1581,10 +1515,8 @@ int _wapi_handle_wait_signal_handle (gpointer handle, gboolean alertable)
 int _wapi_handle_timedwait_signal_handle (gpointer handle,
                                                                                  struct timespec *timeout, gboolean alertable, gboolean poll)
 {
-#ifdef DEBUG
-       g_message ("%s: waiting for %p (type %s)", __func__, handle,
+       DEBUG ("%s: waiting for %p (type %s)", __func__, handle,
                   _wapi_handle_typename[_wapi_handle_type (handle)]);
-#endif
        
        if (_WAPI_SHARED_HANDLE (_wapi_handle_type (handle))) {
                if (WAPI_SHARED_HANDLE_DATA(handle).signalled == TRUE) {
@@ -1649,6 +1581,7 @@ _wapi_free_share_info (_WapiFileShare *share_info)
                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));
        }
@@ -1810,6 +1743,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)) {
@@ -1817,12 +1753,11 @@ static void _wapi_handle_check_share_by_pid (struct _WapiFileShare *share_info)
                 * owned by someone else) so mark this share info as
                 * dead
                 */
-#ifdef DEBUG
-               g_message ("%s: Didn't find it, destroying entry", __func__);
-#endif
+               DEBUG ("%s: Didn't find it, destroying entry", __func__);
 
-               memset (share_info, '\0', sizeof(struct _WapiFileShare));
+               _wapi_free_share_info (share_info);
        }
+#endif
 }
 
 #ifdef __linux__
@@ -1869,10 +1804,8 @@ 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) {
-#ifdef DEBUG
-                                       g_message ("%s: handle 0x%x has this file open!",
+                                       DEBUG ("%s: handle 0x%x has this file open!",
                                                           __func__, i);
-#endif
 
                                        goto done;
                                }
@@ -1906,9 +1839,7 @@ void _wapi_handle_check_share (struct _WapiFileShare *share_info, int fd)
                                continue;
                        }
 
-#ifdef DEBUG
-                       g_message ("%s: Looking in %s", __func__, subdir);
-#endif
+                       DEBUG ("%s: Looking in %s", __func__, subdir);
                        
                        proc_fds = TRUE;
                        
@@ -1930,10 +1861,8 @@ void _wapi_handle_check_share (struct _WapiFileShare *share_info, int fd)
                                stat (path, &link_stat);
                                if (link_stat.st_dev == share_info->device &&
                                    link_stat.st_ino == share_info->inode) {
-#ifdef DEBUG
-                                       g_message ("%s:  Found it at %s",
+                                       DEBUG ("%s:  Found it at %s",
                                                   __func__, path);
-#endif
 
                                        found = TRUE;
                                }
@@ -1947,11 +1876,9 @@ 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 */
-#ifdef DEBUG
-               g_message ("%s: Didn't find it, destroying entry", __func__);
-#endif
+               DEBUG ("%s: Didn't find it, destroying entry", __func__);
 
-               memset (share_info, '\0', sizeof(struct _WapiFileShare));
+               _wapi_free_share_info (share_info);
        }
 
 done:
@@ -2051,29 +1978,21 @@ void _wapi_handle_update_refs (void)
                                if (_WAPI_SHARED_HANDLE(handle->type)) {
                                        struct _WapiHandleShared *shared_data;
                                
-#ifdef DEBUG
-                                       g_message ("%s: (%d) handle 0x%x is SHARED (%s)", __func__, _wapi_getpid (), i * _WAPI_HANDLE_INITIAL_COUNT + k, _wapi_handle_typename[handle->type]);
-#endif
+                                       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];
 
-#ifdef DEBUG
-                                       g_message ("%s: (%d) Updating timestamp of handle 0x%x", __func__, _wapi_getpid (), handle->u.shared.offset);
-#endif
+                                       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;
                                
-#ifdef DEBUG
-                                       g_message ("%s: (%d) handle 0x%x is FILE", __func__, _wapi_getpid (), i * _WAPI_HANDLE_INITIAL_COUNT + k);
-#endif
+                                       DEBUG ("%s: (%d) handle 0x%x is FILE", __func__, _wapi_getpid (), i * _WAPI_HANDLE_INITIAL_COUNT + k);
                                
                                        g_assert (file_handle->share_info != NULL);
 
-#ifdef DEBUG
-                                       g_message ("%s: (%d) Inc refs on fileshare 0x%x", __func__, _wapi_getpid (), (file_handle->share_info - &_wapi_fileshare_layout->share_info[0]) / sizeof(struct _WapiFileShare));
-#endif
+                                       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);
                                }