X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fio-layer%2Fhandles-private.h;h=c5d4fbeb70e94f400e7824cc1db1373a6f465094;hb=8eeb2cef8fb37b7aaeed5fb0c31550a1701f9bdf;hp=e2d841dc02e1e7119dabaa140e46dd90a6e4b514;hpb=af90548a08ef5effc93b083b7eec44daa178b141;p=mono.git diff --git a/mono/io-layer/handles-private.h b/mono/io-layer/handles-private.h index e2d841dc02e..c5d4fbeb70e 100644 --- a/mono/io-layer/handles-private.h +++ b/mono/io-layer/handles-private.h @@ -13,7 +13,6 @@ #include #include #include -#include #include #include @@ -21,8 +20,9 @@ #include #include #include +#include -#define _WAPI_PRIVATE_MAX_SLOTS 1024 +#define _WAPI_PRIVATE_MAX_SLOTS (1024 * 16) #define _WAPI_PRIVATE_HANDLES(x) (_wapi_private_handles [x / _WAPI_HANDLE_INITIAL_COUNT][x % _WAPI_HANDLE_INITIAL_COUNT]) #define _WAPI_PRIVATE_HAVE_SLOT(x) ((GPOINTER_TO_UINT (x) / _WAPI_PRIVATE_MAX_SLOTS) < _WAPI_PRIVATE_MAX_SLOTS && \ _wapi_private_handles [GPOINTER_TO_UINT (x) / _WAPI_HANDLE_INITIAL_COUNT] != NULL) @@ -35,9 +35,10 @@ extern struct _WapiHandleSharedLayout *_wapi_shared_layout; extern struct _WapiFileShareLayout *_wapi_fileshare_layout; extern guint32 _wapi_fd_reserve; -extern mono_mutex_t _wapi_global_signal_mutex; -extern pthread_cond_t _wapi_global_signal_cond; +extern mono_mutex_t *_wapi_global_signal_mutex; +extern pthread_cond_t *_wapi_global_signal_cond; extern int _wapi_sem_id; +extern gboolean _wapi_has_shut_down; extern pid_t _wapi_getpid (void); extern gpointer _wapi_handle_new (WapiHandleType type, @@ -67,7 +68,8 @@ extern void _wapi_handle_ops_signal (gpointer handle); extern gboolean _wapi_handle_ops_own (gpointer handle); extern gboolean _wapi_handle_ops_isowned (gpointer handle); extern guint32 _wapi_handle_ops_special_wait (gpointer handle, - guint32 timeout); + guint32 timeout, + gboolean alertable); extern void _wapi_handle_ops_prewait (gpointer handle); extern gboolean _wapi_handle_count_signalled_handles (guint32 numhandles, @@ -77,12 +79,9 @@ extern gboolean _wapi_handle_count_signalled_handles (guint32 numhandles, guint32 *lowest); extern void _wapi_handle_unlock_handles (guint32 numhandles, gpointer *handles); -extern int _wapi_handle_wait_signal (void); -extern int _wapi_handle_timedwait_signal (struct timespec *timeout); -extern int _wapi_handle_wait_signal_handle (gpointer handle, gboolean alertable); -extern int _wapi_handle_timedwait_signal_handle (gpointer handle, - struct timespec *timeout, gboolean alertable); -extern gboolean _wapi_handle_get_or_set_share (dev_t device, ino_t inode, +extern int _wapi_handle_timedwait_signal (struct timespec *timeout, gboolean poll, gboolean *alerted); +extern int _wapi_handle_timedwait_signal_handle (gpointer handle, struct timespec *timeout, gboolean alertable, gboolean poll, gboolean *alerted); +extern gboolean _wapi_handle_get_or_set_share (guint64 device, guint64 inode, guint32 new_sharemode, guint32 new_access, guint32 *old_sharemode, @@ -95,6 +94,7 @@ extern void _wapi_handle_update_refs (void); extern void _wapi_handle_foreach (WapiHandleType type, gboolean (*on_each)(gpointer test, gpointer user), gpointer user_data); +void _wapi_free_share_info (_WapiFileShare *share_info); /* This is OK to use for atomic writes of individual struct members, as they * are independent @@ -107,8 +107,8 @@ static inline WapiHandleType _wapi_handle_type (gpointer handle) { guint32 idx = GPOINTER_TO_UINT(handle); - if (!_WAPI_PRIVATE_VALID_SLOT (idx)) { - return(WAPI_HANDLE_COUNT); /* An impossible type */ + if (!_WAPI_PRIVATE_VALID_SLOT (idx) || !_WAPI_PRIVATE_HAVE_SLOT (idx)) { + return(WAPI_HANDLE_UNUSED); /* An impossible type */ } return(_WAPI_PRIVATE_HANDLES(idx).type); @@ -138,6 +138,14 @@ static inline void _wapi_handle_set_signal_state (gpointer handle, if (state == TRUE) { /* Tell everyone blocking on a single handle */ + /* The condition the global signal cond is waiting on is the signalling of + * _any_ handle. So lock it before setting the signalled state. + */ + thr_ret = mono_mutex_lock (_wapi_global_signal_mutex); + if (thr_ret != 0) + g_warning ("Bad call to mono_mutex_lock result %d for global signal mutex", thr_ret); + g_assert (thr_ret == 0); + /* This function _must_ be called with * handle->signal_mutex locked */ @@ -145,25 +153,28 @@ static inline void _wapi_handle_set_signal_state (gpointer handle, if (broadcast == TRUE) { thr_ret = pthread_cond_broadcast (&handle_data->signal_cond); + if (thr_ret != 0) + g_warning ("Bad call to pthread_cond_broadcast result %d for handle %p", thr_ret, handle); g_assert (thr_ret == 0); } else { thr_ret = pthread_cond_signal (&handle_data->signal_cond); + if (thr_ret != 0) + g_warning ("Bad call to pthread_cond_signal result %d for handle %p", thr_ret, handle); g_assert (thr_ret == 0); } /* Tell everyone blocking on multiple handles that something * was signalled - */ - pthread_cleanup_push ((void(*)(void *))mono_mutex_unlock_in_cleanup, (void *)&_wapi_global_signal_mutex); - thr_ret = mono_mutex_lock (&_wapi_global_signal_mutex); + */ + thr_ret = pthread_cond_broadcast (_wapi_global_signal_cond); + if (thr_ret != 0) + g_warning ("Bad call to pthread_cond_broadcast result %d for handle %p", thr_ret, handle); g_assert (thr_ret == 0); - thr_ret = pthread_cond_broadcast (&_wapi_global_signal_cond); + thr_ret = mono_mutex_unlock (_wapi_global_signal_mutex); + if (thr_ret != 0) + g_warning ("Bad call to mono_mutex_unlock result %d for global signal mutex", thr_ret); g_assert (thr_ret == 0); - - thr_ret = mono_mutex_unlock (&_wapi_global_signal_mutex); - g_assert (thr_ret == 0); - pthread_cleanup_pop (0); } else { handle_data->signalled=state; } @@ -216,7 +227,7 @@ static inline int _wapi_handle_lock_signal_mutex (void) g_message ("%s: lock global signal mutex", __func__); #endif - return(mono_mutex_lock (&_wapi_global_signal_mutex)); + return(mono_mutex_lock (_wapi_global_signal_mutex)); } /* the parameter makes it easier to call from a pthread cleanup handler */ @@ -226,7 +237,7 @@ static inline int _wapi_handle_unlock_signal_mutex (void *unused) g_message ("%s: unlock global signal mutex", __func__); #endif - return(mono_mutex_unlock (&_wapi_global_signal_mutex)); + return(mono_mutex_unlock (_wapi_global_signal_mutex)); } static inline int _wapi_handle_lock_handle (gpointer handle) @@ -343,7 +354,7 @@ static inline int _wapi_namespace_unlock (gpointer data G_GNUC_UNUSED) static inline void _wapi_handle_share_release (struct _WapiFileShare *info) { int thr_ret; - + g_assert (info->handle_refs > 0); /* Prevent new entries racing with us */ @@ -351,7 +362,7 @@ static inline void _wapi_handle_share_release (struct _WapiFileShare *info) g_assert(thr_ret == 0); if (InterlockedDecrement ((gint32 *)&info->handle_refs) == 0) { - memset (info, '\0', sizeof(struct _WapiFileShare)); + _wapi_free_share_info (info); } thr_ret = _wapi_shm_sem_unlock (_WAPI_SHARED_SEM_FILESHARE);