Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions src/mono/mono/utils/mono-threads-coop.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,10 +337,10 @@ mono_threads_exit_gc_safe_region_internal (gpointer cookie, MonoStackData *stack
return;

#ifdef ENABLE_CHECKED_BUILD_GC
W32_DEFINE_LAST_ERROR_RESTORE_POINT;
MONO_DEFINE_LAST_ERROR_RESTORE_POINT;
if (mono_check_mode_enabled (MONO_CHECK_MODE_GC))
coop_tls_pop (cookie);
W32_RESTORE_LAST_ERROR_FROM_RESTORE_POINT;
MONO_RESTORE_LAST_ERROR_FROM_RESTORE_POINT;
#endif

mono_threads_exit_gc_safe_region_unbalanced_internal (cookie, stackdata);
Expand All @@ -365,7 +365,7 @@ mono_threads_exit_gc_safe_region_unbalanced_internal (gpointer cookie, MonoStack
/* Common to use enter/exit gc safe around OS API's affecting last error. */
/* This method can call OS API's that will reset last error on some platforms. */
/* To reduce errors, we need to restore last error before exit gc safe. */
W32_DEFINE_LAST_ERROR_RESTORE_POINT;
MONO_DEFINE_LAST_ERROR_RESTORE_POINT;

info = (MonoThreadInfo *)cookie;

Expand Down Expand Up @@ -398,7 +398,7 @@ mono_threads_exit_gc_safe_region_unbalanced_internal (gpointer cookie, MonoStack
info->user_data = NULL;
}

W32_RESTORE_LAST_ERROR_FROM_RESTORE_POINT;
MONO_RESTORE_LAST_ERROR_FROM_RESTORE_POINT;
}

void
Expand Down Expand Up @@ -652,14 +652,14 @@ mono_threads_suspend_policy_init (void)
// otherwise if one of the old environment variables is set, use that.
// otherwise use full preemptive suspend.

W32_DEFINE_LAST_ERROR_RESTORE_POINT;
MONO_DEFINE_LAST_ERROR_RESTORE_POINT;

(policy = threads_suspend_policy_getenv ())
|| (policy = threads_suspend_policy_default ())
|| (policy = threads_suspend_policy_getenv_compat ())
|| (policy = MONO_THREADS_SUSPEND_FULL_PREEMPTIVE);

W32_RESTORE_LAST_ERROR_FROM_RESTORE_POINT;
MONO_RESTORE_LAST_ERROR_FROM_RESTORE_POINT;

g_assert (policy);
mono_threads_suspend_policy_hidden_dont_modify = (char)policy;
Expand Down
4 changes: 2 additions & 2 deletions src/mono/mono/utils/mono-threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -1938,7 +1938,7 @@ mono_thread_info_uninstall_interrupt (gboolean *interrupted)
/* Common to uninstall interrupt handler around OS API's affecting last error. */
/* This method could call OS API's on some platforms that will reset last error so make sure to restore */
/* last error before exit. */
W32_DEFINE_LAST_ERROR_RESTORE_POINT;
MONO_DEFINE_LAST_ERROR_RESTORE_POINT;

g_assert (interrupted);
*interrupted = FALSE;
Expand All @@ -1961,7 +1961,7 @@ mono_thread_info_uninstall_interrupt (gboolean *interrupted)
THREADS_INTERRUPT_DEBUG ("interrupt uninstall tid %p previous_token %p interrupted %s\n",
mono_thread_info_get_tid (info), previous_token, *interrupted ? "TRUE" : "FALSE");

W32_RESTORE_LAST_ERROR_FROM_RESTORE_POINT;
MONO_RESTORE_LAST_ERROR_FROM_RESTORE_POINT;
}

static MonoThreadInfoInterruptToken*
Expand Down
41 changes: 36 additions & 5 deletions src/mono/mono/utils/mono-threads.h
Original file line number Diff line number Diff line change
Expand Up @@ -871,19 +871,50 @@ mono_win32_interrupt_wait (PVOID thread_info, HANDLE native_thread_handle, DWORD
void
mono_win32_abort_blocking_io_call (THREAD_INFO_TYPE *info);

#define W32_DEFINE_LAST_ERROR_RESTORE_POINT \
#else


#endif

#ifdef USE_WINDOWS_BACKEND

/* APC calls can change GetLastError while a thread is suspended. Save/restore it when doing thread
state transitions (for example in m2n wrappers) in order to protect the result of the last
pinvoke */

#define MONO_DEFINE_LAST_ERROR_RESTORE_POINT \
const DWORD _last_error_restore_point = GetLastError ();

#define W32_RESTORE_LAST_ERROR_FROM_RESTORE_POINT \
#define MONO_RESTORE_LAST_ERROR_FROM_RESTORE_POINT \
/* Only restore if changed to prevent unnecessary writes. */ \
if (GetLastError () != _last_error_restore_point) \
mono_SetLastError (_last_error_restore_point);

#else
#elif defined(USE_WASM_BACKEND) || defined (USE_POSIX_BACKEND)

#define W32_DEFINE_LAST_ERROR_RESTORE_POINT /* nothing */
#define W32_RESTORE_LAST_ERROR_FROM_RESTORE_POINT /* nothing */
#define MONO_DEFINE_LAST_ERROR_RESTORE_POINT \
int _last_errno_restore_point = errno;

#define MONO_RESTORE_LAST_ERROR_FROM_RESTORE_POINT \
if (errno != _last_errno_restore_point) \
errno = _last_errno_restore_point;

/* Posix semaphores set errno on failure and sporadic wakeup. GC state transitions are done in n2m
* and m2n wrappers and may change the value of errno from the last pinvoke. Use these macros to
* save/restore errno when doing thread state transitions. */

#elif defined(USE_MACH_BACKEND)

/* Mach semaphores don't set errno on failure. Change this to be the same as POSIX if some other primitives used
in thread state transitions pollute errno. */

#define MONO_DEFINE_LAST_ERROR_RESTORE_POINT /* nothing */
#define MONO_RESTORE_LAST_ERROR_FROM_RESTORE_POINT /* nothing */

#else
#error "unknown threads backend, not sure how to save/restore last error"
#endif



#endif /* __MONO_THREADS_H__ */