Author: dick
Date: 2005-04-28 11:38:47 -0400 (Thu, 28 Apr 2005)
New Revision: 43728
Modified:
trunk/mono/mono/io-layer/ChangeLog
trunk/mono/mono/io-layer/handles-private.h
trunk/mono/mono/io-layer/handles.c
trunk/mono/mono/io-layer/mutexes.c
trunk/mono/mono/io-layer/processes.c
Log:
2005-04-28 Dick Porter <[EMAIL PROTECTED]>
* processes.c: Cope with handles that are only around for as long
as the search is running. If we're searching for process handles,
check to see if the process is still running and signal it if not.
* handles.c (_wapi_search_handle): Search in the shared space as
well. Fixed bug 74752.
* mutexes.c:
* handles.c (_wapi_handle_new_from_offset):
_wapi_handle_new_for_existing_ns () was doing exactly the same as
this, so deleted it.
Modified: trunk/mono/mono/io-layer/ChangeLog
===================================================================
--- trunk/mono/mono/io-layer/ChangeLog 2005-04-28 15:28:32 UTC (rev 43727)
+++ trunk/mono/mono/io-layer/ChangeLog 2005-04-28 15:38:47 UTC (rev 43728)
@@ -1,3 +1,17 @@
+2005-04-28 Dick Porter <[EMAIL PROTECTED]>
+
+ * processes.c: Cope with handles that are only around for as long
+ as the search is running. If we're searching for process handles,
+ check to see if the process is still running and signal it if not.
+
+ * handles.c (_wapi_search_handle): Search in the shared space as
+ well. Fixed bug 74752.
+
+ * mutexes.c:
+ * handles.c (_wapi_handle_new_from_offset):
+ _wapi_handle_new_for_existing_ns () was doing exactly the same as
+ this, so deleted it.
+
2005-04-26 Dick Porter <[EMAIL PROTECTED]>
* handles.c: Fix stupid thinko where if a new shared handle is
Modified: trunk/mono/mono/io-layer/handles-private.h
===================================================================
--- trunk/mono/mono/io-layer/handles-private.h 2005-04-28 15:28:32 UTC (rev
43727)
+++ trunk/mono/mono/io-layer/handles-private.h 2005-04-28 15:38:47 UTC (rev
43728)
@@ -36,12 +36,10 @@
extern gpointer _wapi_handle_new (WapiHandleType type,
gpointer handle_specific);
-extern gpointer _wapi_handle_new_for_existing_ns (WapiHandleType type,
- gpointer handle_specific,
- guint32 offset);
extern gpointer _wapi_handle_new_fd (WapiHandleType type, int fd,
gpointer handle_specific);
-extern gpointer _wapi_handle_new_from_offset (WapiHandleType type, int offset);
+extern gpointer _wapi_handle_new_from_offset (WapiHandleType type,
+ guint32 offset);
extern gboolean _wapi_lookup_handle (gpointer handle, WapiHandleType type,
gpointer *handle_specific);
extern gboolean _wapi_copy_handle (gpointer handle, WapiHandleType type,
Modified: trunk/mono/mono/io-layer/handles.c
===================================================================
--- trunk/mono/mono/io-layer/handles.c 2005-04-28 15:28:32 UTC (rev 43727)
+++ trunk/mono/mono/io-layer/handles.c 2005-04-28 15:38:47 UTC (rev 43728)
@@ -397,9 +397,7 @@
return(handle);
}
-gpointer _wapi_handle_new_for_existing_ns (WapiHandleType type,
- gpointer handle_specific,
- guint32 offset)
+gpointer _wapi_handle_new_from_offset (WapiHandleType type, guint32 offset)
{
guint32 handle_idx = 0;
gpointer handle;
@@ -408,8 +406,8 @@
mono_once (&shared_init_once, shared_init);
#ifdef DEBUG
- g_message ("%s: Creating new handle of type %s", __func__,
- _wapi_handle_typename[type]);
+ g_message ("%s: Creating new handle of type %s to offset %d", __func__,
+ _wapi_handle_typename[type], offset);
#endif
g_assert(!_WAPI_FD_HANDLE(type));
@@ -438,7 +436,7 @@
thr_ret = mono_mutex_lock (&scan_mutex);
g_assert (thr_ret == 0);
- while ((handle_idx = _wapi_handle_new_internal (type, handle_specific))
== 0) {
+ while ((handle_idx = _wapi_handle_new_internal (type, NULL)) == 0) {
/* Try and expand the array, and have another go */
int idx = SLOT_INDEX (_wapi_private_handle_count);
_wapi_private_handles [idx] = g_new0 (struct
_WapiHandleUnshared,
@@ -509,57 +507,6 @@
return(GUINT_TO_POINTER(fd));
}
-gpointer _wapi_handle_new_from_offset (WapiHandleType type, int offset)
-{
- guint32 handle_idx = 0;
- gpointer handle;
- int thr_ret;
- struct _WapiHandle_shared_ref *ref;
- struct _WapiHandleUnshared *handle_data;
-
- mono_once (&shared_init_once, shared_init);
-
-#ifdef DEBUG
- g_message ("%s: Creating new handle of type %s to offset %d", __func__,
- _wapi_handle_typename[type], offset);
-#endif
-
- g_assert(_WAPI_SHARED_HANDLE(type));
-
- pthread_cleanup_push ((void(*)(void *))mono_mutex_unlock_in_cleanup,
- (void *)&scan_mutex);
- thr_ret = mono_mutex_lock (&scan_mutex);
- g_assert(thr_ret == 0);
-
- while ((handle_idx = _wapi_handle_new_internal (type, NULL)) == 0) {
- /* Try and expand the array, and have another go */
- int idx = SLOT_INDEX (_wapi_private_handle_count);
- _wapi_private_handles [idx] = g_new0 (struct
_WapiHandleUnshared,
- _WAPI_HANDLE_INITIAL_COUNT);
-
- _wapi_private_handle_count += _WAPI_HANDLE_INITIAL_COUNT;
- }
-
- thr_ret = mono_mutex_unlock (&scan_mutex);
- g_assert (thr_ret == 0);
- pthread_cleanup_pop (0);
-
- /* Make sure we left the space for fd mappings */
- g_assert (handle_idx >= _wapi_fd_reserve);
-
- handle_data = &_WAPI_PRIVATE_HANDLES(handle_idx);
- ref = &handle_data->u.shared;
- ref->offset = offset;
-
- handle = GUINT_TO_POINTER (handle_idx);
-
-#ifdef DEBUG
- g_message ("%s: Allocated new handle %p", __func__, handle);
-#endif
-
- return (handle);
-}
-
gboolean _wapi_lookup_handle (gpointer handle, WapiHandleType type,
gpointer *handle_specific)
{
@@ -715,9 +662,12 @@
return (TRUE);
}
-/* This will only find shared handles that have already been opened by
- * this process. To look up shared handles by name, use
- * _wapi_search_handle_namespace
+/* This might list some shared handles twice if they are already
+ * opened by this process, and the check function returns FALSE the
+ * first time. Shared handles that are created during the search are
+ * unreffed if the check function returns FALSE, so callers must not
+ * rely on the handle persisting (unless the check function returns
+ * TRUE)
*/
gpointer _wapi_search_handle (WapiHandleType type,
gboolean (*check)(gpointer test, gpointer user),
@@ -730,13 +680,13 @@
gboolean found = FALSE;
- for(i = SLOT_INDEX (0); !found && _wapi_private_handles [i] != NULL;
i++) {
+ for (i = SLOT_INDEX (0); !found && _wapi_private_handles [i] != NULL;
i++) {
for (k = SLOT_OFFSET (0); k < _WAPI_HANDLE_INITIAL_COUNT; k++) {
handle_data = &_wapi_private_handles [i][k];
- if(handle_data->type == type) {
+ if (handle_data->type == type) {
ret = GUINT_TO_POINTER (i *
_WAPI_HANDLE_INITIAL_COUNT + k);
- if(check (ret, user_data) == TRUE) {
+ if (check (ret, user_data) == TRUE) {
found = TRUE;
break;
}
@@ -745,6 +695,48 @@
}
if (!found) {
+ /* Not found yet, so search the shared memory too */
+#ifdef DEBUG
+ g_message ("%s: Looking at other shared handles...", __func__);
+#endif
+
+ for (i = 0; i < _WAPI_HANDLE_INITIAL_COUNT; i++) {
+ struct _WapiHandleShared *shared;
+ struct _WapiHandleSharedMetadata *meta;
+ WapiHandleType shared_type;
+
+ _WAPI_HANDLE_COLLECTION_UNSAFE;
+
+ meta = &_wapi_shared_layout->metadata[i];
+ shared = &_wapi_shared_layout->handles[meta->offset];
+ shared_type = shared->type;
+
+ _WAPI_HANDLE_COLLECTION_SAFE;
+
+ if (shared_type == type) {
+ ret = _wapi_handle_new_from_offset (type, i);
+
+#ifdef DEBUG
+ g_message ("%s: Opened tmp handle %p (type %s)
from offset %d", __func__, ret, _wapi_handle_typename[type], meta->offset);
+#endif
+
+ if (check (ret, user_data) == TRUE) {
+ found = TRUE;
+ handle_data =
&_WAPI_PRIVATE_HANDLES(GPOINTER_TO_UINT(ret));
+
+ break;
+ }
+
+ /* This isn't the handle we're looking
+ * for, so drop the reference we took
+ * in _wapi_handle_new_from_offset ()
+ */
+ _wapi_handle_unref (ret);
+ }
+ }
+ }
+
+ if (!found) {
goto done;
}
Modified: trunk/mono/mono/io-layer/mutexes.c
===================================================================
--- trunk/mono/mono/io-layer/mutexes.c 2005-04-28 15:28:32 UTC (rev 43727)
+++ trunk/mono/mono/io-layer/mutexes.c 2005-04-28 15:38:47 UTC (rev 43728)
@@ -454,7 +454,8 @@
/* A new reference to an existing named mutex, so just
* create the private part
*/
- handle = _wapi_handle_new_for_existing_ns
(WAPI_HANDLE_NAMEDMUTEX, &namedmutex_handle, offset);
+ handle = _wapi_handle_new_from_offset (WAPI_HANDLE_NAMEDMUTEX,
+ offset);
}
if (handle == _WAPI_HANDLE_INVALID) {
Modified: trunk/mono/mono/io-layer/processes.c
===================================================================
--- trunk/mono/mono/io-layer/processes.c 2005-04-28 15:28:32 UTC (rev
43727)
+++ trunk/mono/mono/io-layer/processes.c 2005-04-28 15:38:47 UTC (rev
43728)
@@ -766,13 +766,63 @@
return(current_process_handle->id);
}
+/* Returns the process id as a convenience to the functions that call this */
+static pid_t signal_process_if_gone (gpointer handle)
+{
+ struct _WapiHandle_process *process_handle;
+ gboolean ok;
+
+ /* Make sure the process is signalled if it has exited - if
+ * the parent process didn't wait for it then it won't be
+ */
+ ok = _wapi_lookup_handle (handle, WAPI_HANDLE_PROCESS,
+ (gpointer *)&process_handle);
+ if (ok == FALSE) {
+ g_warning ("%s: error looking up process handle %p",
+ __func__, handle);
+
+ return (0);
+ }
+
+#ifdef DEBUG
+ g_message ("%s: looking at process %d", __func__, process_handle->id);
+#endif
+
+ if (kill (process_handle->id, 0) == -1 &&
+ (errno == ESRCH ||
+ errno == EPERM)) {
+ /* The process is dead, (EPERM tells us a new process
+ * has that ID, but as it's owned by someone else it
+ * can't be the one listed in our shared memory file)
+ */
+ _wapi_shared_handle_set_signal_state (handle, TRUE);
+ }
+
+ return (process_handle->id);
+}
+
static gboolean process_enum (gpointer handle, gpointer user_data)
{
GPtrArray *processes=user_data;
+ pid_t pid = signal_process_if_gone (handle);
+ if (pid == 0) {
+ return (FALSE);
+ }
+
/* Ignore processes that have already exited (ie they are signalled) */
- if(_wapi_handle_issignalled (handle)==FALSE) {
- g_ptr_array_add (processes, handle);
+ if (_wapi_handle_issignalled (handle) == FALSE) {
+#ifdef DEBUG
+ g_message ("%s: process %d added to array", __func__, pid);
+#endif
+
+ /* This ensures that duplicates aren't returned (see
+ * the comment above _wapi_search_handle () for why
+ * it's needed
+ */
+ g_ptr_array_remove (processes, GUINT_TO_POINTER(pid));
+
+ g_ptr_array_add (processes, GUINT_TO_POINTER(pid));
}
/* Return false to keep searching */
@@ -791,19 +841,7 @@
fit=len/sizeof(guint32);
for (i = 0, j = 0; j < fit && i < processes->len; i++) {
- struct _WapiHandle_process *process_handle;
- gboolean ok;
-
- ok=_wapi_lookup_handle (g_ptr_array_index (processes, i),
- WAPI_HANDLE_PROCESS,
- (gpointer *)&process_handle);
- if (ok == TRUE) {
- pids[j++] = process_handle->id;
- } else {
- /* Handle must have been deleted while we were
- * looking through the list
- */
- }
+ pids[j++] = GPOINTER_TO_UINT(g_ptr_array_index (processes, i));
}
g_ptr_array_free (processes, FALSE);
@@ -815,26 +853,21 @@
static gboolean process_open_compare (gpointer handle, gpointer user_data)
{
- struct _WapiHandle_process *process_handle;
- gboolean ok;
- pid_t pid;
-
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_PROCESS,
- (gpointer *)&process_handle);
- if(ok==FALSE) {
- g_warning ("%s: error looking up process handle %p", __func__,
- handle);
+ pid_t wanted_pid;
+ pid_t checking_pid = signal_process_if_gone (handle);
+
+ if (checking_pid == 0) {
return(FALSE);
}
+
+ wanted_pid = GPOINTER_TO_UINT (user_data);
- pid=GPOINTER_TO_UINT (user_data);
-
/* It's possible to have more than one process handle with the
* same pid, but only the one running process can be
* unsignalled
*/
- if(process_handle->id==pid &&
- _wapi_handle_issignalled (handle)==FALSE) {
+ if (checking_pid == wanted_pid &&
+ _wapi_handle_issignalled (handle) == FALSE) {
return(TRUE);
} else {
return(FALSE);
@@ -848,14 +881,19 @@
mono_once (&process_current_once, process_set_current);
- handle=_wapi_search_handle (WAPI_HANDLE_PROCESS, process_open_compare,
- GUINT_TO_POINTER (pid), NULL);
- if(handle==0) {
#ifdef DEBUG
+ g_message ("%s: looking for process %d", __func__, pid);
+#endif
+
+ handle = _wapi_search_handle (WAPI_HANDLE_PROCESS,
+ process_open_compare,
+ GUINT_TO_POINTER (pid), NULL);
+ if (handle == 0) {
+#ifdef DEBUG
g_message ("%s: Can't find pid %d", __func__, pid);
#endif
- /* Set an error code */
+ SetLastError (ERROR_PROC_NOT_FOUND);
return(NULL);
}
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches