_wapi_daemon_response (g_io_channel_unix_get_fd (channel), resp);
}
-/*
- * process_new:
- * @channel: The client making the request
- * @channel_data: Our data for this channel
- * @type: type to init handle to
- *
- * Find a free handle and initialize it to 'type', increase refcnt and
- * send back a reply to the client.
- */
-static void process_new (GIOChannel *channel, ChannelData *channel_data,
- WapiHandleType type)
+static guint32 new_handle_with_shared_check (WapiHandleType type)
{
- guint32 handle;
- WapiHandleResponse resp={0};
-
- handle=_wapi_handle_new_internal (type);
- if(handle==0) {
+ guint32 handle = 0;
+
+ while ((handle = _wapi_handle_new_internal (type)) == 0) {
/* Try and allocate a new shared segment, and have
* another go
*/
channels[i].open_handles=_wapi_g_renew0 (channels[i].open_handles, old_len, new_len);
}
}
-
- handle=_wapi_handle_new_internal (type);
} else {
/* Map failed. Just return 0 meaning "out of
* handles"
*/
+ break;
}
}
+ return(handle);
+}
+
+/*
+ * process_new:
+ * @channel: The client making the request
+ * @channel_data: Our data for this channel
+ * @type: type to init handle to
+ *
+ * Find a free handle and initialize it to 'type', increase refcnt and
+ * send back a reply to the client.
+ */
+static void process_new (GIOChannel *channel, ChannelData *channel_data,
+ WapiHandleType type)
+{
+ guint32 handle;
+ WapiHandleResponse resp={0};
+
+ handle = new_handle_with_shared_check (type);
+
/* handle might still be set to 0. This is handled at the
* client end
*/
* client must check if either handle is 0 and take
* appropriate error handling action.
*/
- process_handle=_wapi_handle_new_internal (WAPI_HANDLE_PROCESS);
+ process_handle = new_handle_with_shared_check (WAPI_HANDLE_PROCESS);
ref_handle (daemon_channel_data, process_handle);
ref_handle (channel_data, process_handle);
- thread_handle=_wapi_handle_new_internal (WAPI_HANDLE_THREAD);
+ thread_handle = new_handle_with_shared_check (WAPI_HANDLE_THREAD);
ref_handle (daemon_channel_data, thread_handle);
ref_handle (channel_data, thread_handle);
resp.u.process_fork.pid=pid;
}
-
+
resp.u.process_fork.process_handle=process_handle;
resp.u.process_fork.thread_handle=thread_handle;
_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
*/
gboolean CloseHandle(gpointer handle)
{
+ if (handle == NULL) {
+ return(FALSE);
+ }
+
_wapi_handle_unref (handle);
return(TRUE);
* 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 {