ret = mono_w32handle_wait_one (handle, timeout, alertable);
if (ret == MONO_W32HANDLE_WAIT_RET_SUCCESS_0)
return WAIT_OBJECT_0;
+ else if (ret == MONO_W32HANDLE_WAIT_RET_ABANDONED_0)
+ return WAIT_ABANDONED_0;
else if (ret == MONO_W32HANDLE_WAIT_RET_ALERTED)
return WAIT_IO_COMPLETION;
else if (ret == MONO_W32HANDLE_WAIT_RET_TIMEOUT)
ret = mono_w32handle_signal_and_wait (signal_handle, wait, timeout, alertable);
if (ret == MONO_W32HANDLE_WAIT_RET_SUCCESS_0)
return WAIT_OBJECT_0;
+ else if (ret == MONO_W32HANDLE_WAIT_RET_ABANDONED_0)
+ return WAIT_ABANDONED_0;
else if (ret == MONO_W32HANDLE_WAIT_RET_ALERTED)
return WAIT_IO_COMPLETION;
else if (ret == MONO_W32HANDLE_WAIT_RET_TIMEOUT)
MonoW32HandleWaitRet ret;
ret = mono_w32handle_wait_multiple (handles, numobjects, waitall, timeout, alertable);
- if (ret >= MONO_W32HANDLE_WAIT_RET_SUCCESS_0)
+ if (ret >= MONO_W32HANDLE_WAIT_RET_SUCCESS_0 && ret <= MONO_W32HANDLE_WAIT_RET_SUCCESS_0 + numobjects - 1)
return WAIT_OBJECT_0 + (ret - MONO_W32HANDLE_WAIT_RET_SUCCESS_0);
+ else if (ret >= MONO_W32HANDLE_WAIT_RET_ABANDONED_0 && ret <= MONO_W32HANDLE_WAIT_RET_ABANDONED_0 + numobjects - 1)
+ return WAIT_ABANDONED_0 + (ret - MONO_W32HANDLE_WAIT_RET_ABANDONED_0);
else if (ret == MONO_W32HANDLE_WAIT_RET_ALERTED)
return WAIT_IO_COMPLETION;
else if (ret == MONO_W32HANDLE_WAIT_RET_TIMEOUT)
MonoW32HandleNamespace sharedns;
};
-static gboolean event_handle_own (gpointer handle, MonoW32HandleType type)
+static gboolean event_handle_own (gpointer handle, MonoW32HandleType type, guint32 *statuscode)
{
MonoW32HandleEvent *event_handle;
gboolean ok;
+ *statuscode = WAIT_OBJECT_0;
+
ok = mono_w32handle_lookup (handle, type, (gpointer *)&event_handle);
if (!ok) {
g_warning ("%s: error looking up %s handle %p",
ves_icall_System_Threading_Events_SetEvent_internal (handle);
}
-static gboolean event_own (gpointer handle)
+static gboolean event_own (gpointer handle, guint32 *statuscode)
{
- return event_handle_own (handle, MONO_W32HANDLE_EVENT);
+ return event_handle_own (handle, MONO_W32HANDLE_EVENT, statuscode);
}
static void namedevent_signal (gpointer handle)
}
/* NB, always called with the shared handle lock held */
-static gboolean namedevent_own (gpointer handle)
+static gboolean namedevent_own (gpointer handle, guint32 *statuscode)
{
- return event_handle_own (handle, MONO_W32HANDLE_NAMEDEVENT);
+ return event_handle_own (handle, MONO_W32HANDLE_NAMEDEVENT, statuscode);
}
static void event_details (gpointer data)
};
static gboolean
-mutex_handle_own (gpointer handle, MonoW32HandleType type)
+mutex_handle_own (gpointer handle, MonoW32HandleType type, guint32 *statuscode)
{
MonoW32HandleMutex *mutex_handle;
+ *statuscode = WAIT_OBJECT_0;
+
if (!mono_w32handle_lookup (handle, type, (gpointer *)&mutex_handle)) {
g_warning ("%s: error looking up %s handle %p", __func__, mono_w32handle_ops_typename (type), handle);
return FALSE;
ves_icall_System_Threading_Mutex_ReleaseMutex_internal (handle);
}
-static gboolean mutex_own (gpointer handle)
+static gboolean mutex_own (gpointer handle, guint32 *statuscode)
{
- return mutex_handle_own (handle, MONO_W32HANDLE_MUTEX);
+ return mutex_handle_own (handle, MONO_W32HANDLE_MUTEX, statuscode);
}
static gboolean mutex_is_owned (gpointer handle)
}
/* NB, always called with the shared handle lock held */
-static gboolean namedmutex_own (gpointer handle)
+static gboolean namedmutex_own (gpointer handle, guint32 *statuscode)
{
- return mutex_handle_own (handle, MONO_W32HANDLE_NAMEDMUTEX);
+ return mutex_handle_own (handle, MONO_W32HANDLE_NAMEDMUTEX, statuscode);
}
static gboolean namedmutex_is_owned (gpointer handle)
{
gpointer handle;
int thr_ret;
+ guint32 statuscode;
mutex_handle->tid = 0;
mutex_handle->recursion = 0;
g_assert (thr_ret == 0);
if (owned)
- mutex_handle_own (handle, type);
+ mutex_handle_own (handle, type, &statuscode);
else
mono_w32handle_set_signal_state (handle, TRUE, FALSE);
MonoW32HandleNamespace sharedns;
};
-static gboolean sem_handle_own (gpointer handle, MonoW32HandleType type)
+static gboolean sem_handle_own (gpointer handle, MonoW32HandleType type, guint32 *statuscode)
{
MonoW32HandleSemaphore *sem_handle;
+ *statuscode = WAIT_OBJECT_0;
+
if (!mono_w32handle_lookup (handle, type, (gpointer *)&sem_handle)) {
g_warning ("%s: error looking up %s handle %p",
__func__, mono_w32handle_ops_typename (type), handle);
ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal(handle, 1, NULL);
}
-static gboolean sema_own (gpointer handle)
+static gboolean sema_own (gpointer handle, guint32 *statuscode)
{
- return sem_handle_own (handle, MONO_W32HANDLE_SEM);
+ return sem_handle_own (handle, MONO_W32HANDLE_SEM, statuscode);
}
static void namedsema_signal (gpointer handle)
}
/* NB, always called with the shared handle lock held */
-static gboolean namedsema_own (gpointer handle)
+static gboolean namedsema_own (gpointer handle, guint32 *statuscode)
{
- return sem_handle_own (handle, MONO_W32HANDLE_NAMEDSEM);
+ return sem_handle_own (handle, MONO_W32HANDLE_NAMEDSEM, statuscode);
}
static void sema_details (gpointer data)
}
}
-gboolean mono_w32handle_ops_own (gpointer handle)
+gboolean mono_w32handle_ops_own (gpointer handle, guint32 *statuscode)
{
MonoW32HandleBase *handle_data;
MonoW32HandleType type;
type = handle_data->type;
if (handle_ops[type] != NULL && handle_ops[type]->own_handle != NULL) {
- return(handle_ops[type]->own_handle (handle));
+ return(handle_ops[type]->own_handle (handle, statuscode));
} else {
return(FALSE);
}
}
static gboolean
-own_if_signalled (gpointer handle)
+own_if_signalled (gpointer handle, guint32 *statuscode)
{
if (!mono_w32handle_issignalled (handle))
return FALSE;
- mono_w32handle_ops_own (handle);
+ *statuscode = WAIT_OBJECT_0;
+ mono_w32handle_ops_own (handle, statuscode);
return TRUE;
}
static gboolean
-own_if_owned( gpointer handle)
+own_if_owned( gpointer handle, guint32 *statuscode)
{
if (!mono_w32handle_ops_isowned (handle))
return FALSE;
- mono_w32handle_ops_own (handle);
+ *statuscode = WAIT_OBJECT_0;
+ mono_w32handle_ops_own (handle, statuscode);
return TRUE;
}
gboolean alerted;
gint64 start;
gint thr_ret;
+ guint32 statuscode = 0;
alerted = FALSE;
case WAIT_OBJECT_0:
ret = MONO_W32HANDLE_WAIT_RET_SUCCESS_0;
break;
+ case WAIT_ABANDONED_0:
+ ret = MONO_W32HANDLE_WAIT_RET_ABANDONED_0;
+ break;
case WAIT_IO_COMPLETION:
ret = MONO_W32HANDLE_WAIT_RET_ALERTED;
break;
g_assert (thr_ret == 0);
if (mono_w32handle_test_capabilities (handle, MONO_W32HANDLE_CAP_OWN)) {
- if (own_if_owned (handle)) {
+ if (own_if_owned (handle, &statuscode)) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p already owned",
__func__, handle);
for (;;) {
gint waited;
- if (own_if_signalled (handle)) {
+ if (own_if_signalled (handle, &statuscode)) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p signalled",
__func__, handle);
gint i, thr_ret;
gint64 start;
gpointer handles_sorted [MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS];
+ guint32 statuscode = 0;
if (nhandles == 0)
return MONO_W32HANDLE_WAIT_RET_FAILED;
if (signalled) {
for (i = 0; i < nhandles; i++)
- own_if_signalled (handles [i]);
+ own_if_signalled (handles [i], &statuscode);
}
mono_w32handle_unlock_handles (handles, nhandles);
gint64 start;
gboolean alerted;
gint thr_ret;
+ guint32 statuscode = 0;
alerted = FALSE;
mono_w32handle_ops_signal (signal_handle);
if (mono_w32handle_test_capabilities (wait_handle, MONO_W32HANDLE_CAP_OWN)) {
- if (own_if_owned (wait_handle)) {
+ if (own_if_owned (wait_handle, &statuscode)) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p already owned",
__func__, wait_handle);
for (;;) {
gint waited;
- if (own_if_signalled (wait_handle)) {
+ if (own_if_signalled (wait_handle, &statuscode)) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_W32HANDLE, "%s: handle %p signalled",
__func__, wait_handle);
/* Called by WaitForSingleObject and WaitForMultipleObjects,
* with the handle locked (shared handles aren't locked.)
* Returns TRUE if ownership was established, false otherwise.
+ * If TRUE, *statuscode contains a status code such as
+ * WAIT_OBJECT_0 or WAIT_ABANDONED_0.
*/
- gboolean (*own_handle)(gpointer handle);
+ gboolean (*own_handle)(gpointer handle, guint32 *statuscode);
/* Called by WaitForSingleObject and WaitForMultipleObjects, if the
* handle in question is "ownable" (ie mutexes), to see if the current
mono_w32handle_ops_signal (gpointer handle);
gboolean
-mono_w32handle_ops_own (gpointer handle);
+mono_w32handle_ops_own (gpointer handle, guint32 *statuscode);
gboolean
mono_w32handle_ops_isowned (gpointer handle);
mono_w32handle_unlock_handle (gpointer handle);
typedef enum {
- MONO_W32HANDLE_WAIT_RET_SUCCESS_0 = 0,
- MONO_W32HANDLE_WAIT_RET_ALERTED = -1,
- MONO_W32HANDLE_WAIT_RET_TIMEOUT = -2,
- MONO_W32HANDLE_WAIT_RET_FAILED = -3,
+ MONO_W32HANDLE_WAIT_RET_SUCCESS_0 = 0,
+ MONO_W32HANDLE_WAIT_RET_ABANDONED_0 = MONO_W32HANDLE_WAIT_RET_SUCCESS_0 + MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS,
+ MONO_W32HANDLE_WAIT_RET_ALERTED = -1,
+ MONO_W32HANDLE_WAIT_RET_TIMEOUT = -2,
+ MONO_W32HANDLE_WAIT_RET_FAILED = -3,
} MonoW32HandleWaitRet;
MonoW32HandleWaitRet