X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fio-layer%2Fhandles-private.h;h=b74d5bedf82f743a33566272c91762ddb1916d15;hb=f6bbdfd2b00fe866bce76be272ee5e28950bdbd0;hp=2262aa8a2b60fb36fe21209a5cbe44889a23d89f;hpb=379d9d323a20eec101e6a0c3459bf16694e80a3e;p=mono.git diff --git a/mono/io-layer/handles-private.h b/mono/io-layer/handles-private.h index 2262aa8a2b6..b74d5bedf82 100644 --- a/mono/io-layer/handles-private.h +++ b/mono/io-layer/handles-private.h @@ -22,7 +22,7 @@ #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,10 +35,10 @@ extern struct _WapiHandleSharedLayout *_wapi_shared_layout; extern struct _WapiFileShareLayout *_wapi_fileshare_layout; extern guint32 _wapi_fd_reserve; -extern mono_mutex_t _wapi_alertable_mutex; -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, @@ -78,12 +78,11 @@ 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 (gboolean shared); -extern int _wapi_handle_timedwait_signal (struct timespec *timeout, - gboolean shared); +extern int _wapi_handle_wait_signal (gboolean poll); +extern int _wapi_handle_timedwait_signal (struct timespec *timeout, gboolean poll); 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); + struct timespec *timeout, gboolean alertable, gboolean poll); extern gboolean _wapi_handle_get_or_set_share (dev_t device, ino_t inode, guint32 new_sharemode, guint32 new_access, @@ -140,6 +139,15 @@ 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. + */ + pthread_cleanup_push ((void(*)(void *))mono_mutex_unlock_in_cleanup, (void *)_wapi_global_signal_mutex); + 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 */ @@ -147,121 +155,35 @@ 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); - g_assert (thr_ret == 0); - - thr_ret = mono_mutex_unlock (&_wapi_global_signal_mutex); + 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); + pthread_cleanup_pop (0); } else { handle_data->signalled=state; } } -static inline void _wapi_handle_current_thread_set_waiting_on (gpointer waiting_on) -{ - gpointer current_thread = _wapi_thread_handle_from_id (pthread_self ()); - struct _WapiHandle_thread *thread; - gboolean ok; - int thr_ret; - - if (current_thread == NULL) { - return; - } - - if (_WAPI_SHARED_HANDLE(_wapi_handle_type (waiting_on))) { - /* We can't signal shared handles with pthreads, so - * just ignore it here so the problem won't arise - */ - return; - } - - ok = _wapi_lookup_handle (current_thread, WAPI_HANDLE_THREAD, - (gpointer *)&thread); - if (ok == FALSE) { - return; - } - - pthread_cleanup_push ((void(*)(void *))mono_mutex_unlock_in_cleanup, - (void *)&_wapi_alertable_mutex); - thr_ret = mono_mutex_lock (&_wapi_alertable_mutex); - g_assert (thr_ret == 0); - - thread->waiting_on = waiting_on; - - thr_ret = mono_mutex_unlock (&_wapi_alertable_mutex); - g_assert (thr_ret == 0); - pthread_cleanup_pop (0); -} - -static inline void _wapi_handle_trip_signal (gpointer handle) -{ - guint32 idx = GPOINTER_TO_UINT(handle); - struct _WapiHandleUnshared *handle_data; - int thr_ret; - - if (handle == INVALID_HANDLE_VALUE) { - /* 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); - g_assert (thr_ret == 0); - - thr_ret = pthread_cond_broadcast (&_wapi_global_signal_cond); - g_assert (thr_ret == 0); - - thr_ret = mono_mutex_unlock (&_wapi_global_signal_mutex); - g_assert (thr_ret == 0); - pthread_cleanup_pop (0); - - return; - } - - /* handle must be a valid private handle then */ - if (!_WAPI_PRIVATE_VALID_SLOT (idx)) { - return; - } - - g_assert (!_WAPI_SHARED_HANDLE(_wapi_handle_type (handle))); - - handle_data = &_WAPI_PRIVATE_HANDLES(idx); - -#ifdef DEBUG - g_message ("%s: tripping condition of %p", __func__, handle); -#endif - - /* Tell everyone blocking on a single handle */ - - /* This function _must_ be called with handle->signal_mutex - * unlocked - */ - - pthread_cleanup_push ((void(*)(void *))mono_mutex_unlock_in_cleanup, (void *)&handle_data->signal_mutex); - thr_ret = mono_mutex_lock (&handle_data->signal_mutex); - g_assert (thr_ret == 0); - - thr_ret = pthread_cond_broadcast (&handle_data->signal_cond); - g_assert (thr_ret == 0); - - thr_ret = mono_mutex_unlock (&handle_data->signal_mutex); - g_assert (thr_ret == 0); - pthread_cleanup_pop (0); -} - static inline void _wapi_shared_handle_set_signal_state (gpointer handle, gboolean state) { @@ -309,7 +231,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 */ @@ -319,7 +241,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)