_wapi_shared_data=g_new0 (struct _WapiHandleShared_list *, 1);
_wapi_private_data=g_new0 (struct _WapiHandlePrivate_list *, 1);
- /* Build this array at runtime, because I'm guessing that
- * getdtablesize() won't be a fixed value on all systems (or
- * why would it be a function rather than a constant define?)
- */
- _wapi_fd_offset_table_size=getdtablesize ();
- _wapi_fd_offset_table=g_new0 (gpointer, _wapi_fd_offset_table_size);
-
attach_again:
#ifndef DISABLE_SHARED_HANDLES
goto attach_again;
}
+ } else {
+ _wapi_fd_offset_table_size = _wapi_shared_data[0]->fd_offset_table_size;
+ _wapi_fd_offset_table=g_new0 (gpointer, _wapi_fd_offset_table_size);
}
}
_wapi_shared_data[0]->num_segments=1;
_wapi_shared_scratch=g_new0 (struct _WapiHandleScratch, 1);
+
+ _wapi_fd_offset_table_size=getdtablesize ();
+ _wapi_fd_offset_table=g_new0 (gpointer,
+ _wapi_fd_offset_table_size);
}
_wapi_private_data[0]=g_new0 (struct _WapiHandlePrivate_list, 1);
_wapi_shm_mapped_segments=1;
guint32 i, j;
static guint32 last=1;
int thr_ret;
+ guint32 num_segments = _wapi_handle_get_shared_segment (0)->num_segments;
/* A linear scan should be fast enough. Start from the last
* allocation, assuming that handles are allocated more often
#endif
again:
_wapi_handle_segment (GUINT_TO_POINTER (last), &segment, &idx);
- for(i=segment; i<_wapi_handle_get_shared_segment (0)->num_segments;
- i++) {
+ for(i=segment; i < num_segments; i++) {
if(i!=segment) {
idx=0;
}
/* Make sure we dont try and assign the
* handles that would clash with fds
*/
- if (i==0 && j < _wapi_fd_offset_table_size) {
- j = _wapi_fd_offset_table_size;
+ if ((i * _WAPI_HANDLES_PER_SEGMENT + j) < _wapi_fd_offset_table_size) {
+ i = _wapi_fd_offset_table_size / _WAPI_HANDLES_PER_SEGMENT;
+ j = _wapi_fd_offset_table_size - (i * _WAPI_HANDLES_PER_SEGMENT);
+
+ if (i >= num_segments) {
+ /* Need to get the caller to
+ * add more shared segments
+ */
+ return(0);
+ }
+
continue;
}
thr_ret = pthread_mutex_lock (&scan_mutex);
g_assert (thr_ret == 0);
- handle_idx=_wapi_handle_new_internal (type);
- if(handle_idx==0) {
+ while ((handle_idx = _wapi_handle_new_internal (type)) == 0) {
/* Try and get a new segment, and have another go */
segment=_wapi_handle_get_shared_segment (0)->num_segments;
_wapi_handle_ensure_mapped (segment);
if(_wapi_handle_get_shared_segment (segment)!=NULL) {
/* Got a new segment */
_wapi_handle_get_shared_segment (0)->num_segments++;
- handle_idx=_wapi_handle_new_internal (type);
} else {
/* Map failed. Just return 0 meaning
* "out of handles"
_wapi_handle_ops_close_private (handle);
_wapi_handle_get_shared_segment (segment)->handles[idx].type=WAPI_HANDLE_UNUSED;
+ _wapi_handle_get_private_segment (segment)->handles[idx].type=WAPI_HANDLE_UNUSED;
/* Destroy the mutex and cond var. We hope nobody
* tried to grab them between the handle unlock and
handle = _wapi_handle_fd_offset_to_handle (handle);
}
+ if (handle == NULL) {
+ return(FALSE);
+ }
+
_wapi_handle_unref (handle);
return(TRUE);
struct timespec sleepytime;
#ifdef DEBUG
- g_message (G_GNUC_PRETTY_FUNCTION ": attempt failed for %p", handle);
+ g_message (G_GNUC_PRETTY_FUNCTION ": attempt failed for %p: %s", handle, strerror (ret));
#endif
while(i--) {
+ handle = handles[i];
+
+ if (GPOINTER_TO_UINT (handle) < _wapi_fd_offset_table_size) {
+ handle = _wapi_handle_fd_offset_to_handle (handle);
+ }
+
_wapi_handle_segment (handle, &segment, &idx);
thr_ret = mono_mutex_unlock (&_wapi_handle_get_shared_segment (segment)->handles[idx].signal_mutex);
g_assert (thr_ret == 0);
* exec_errno will be set, and the handle will be
* signalled immediately.
*/
- if(process_handle==0 || thread_handle==0) {
+ if(*process_handle==0 || *thread_handle==0) {
return(FALSE);
} else {
+ /* This call returns new handles, so we need to do
+ * a little bookkeeping
+ */
+ if (_wapi_private_data != NULL) {
+ guint32 segment, idx;
+
+ _wapi_handle_segment (*process_handle,
+ &segment, &idx);
+ _wapi_handle_ensure_mapped (segment);
+ _wapi_handle_get_private_segment (segment)->handles[idx].type = WAPI_HANDLE_PROCESS;
+
+ _wapi_handle_segment (*thread_handle,
+ &segment, &idx);
+ _wapi_handle_ensure_mapped (segment);
+ _wapi_handle_get_private_segment (segment)->handles[idx].type = WAPI_HANDLE_THREAD;
+ }
+
return(TRUE);
}
} else {