]> granicus.if.org Git - gc/commit
Prevent GetThreadContext failure (Windows)
authorJonathan Chambers <joncham@gmail.com>
Thu, 5 Sep 2019 09:15:35 +0000 (12:15 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Thu, 5 Sep 2019 09:15:35 +0000 (12:15 +0300)
commit449eda03490bcdd24c958b38fe5d362f0fce5f7c
treedc2eb5c291532afa49c3164a612b6b1be2877457
parent5ff5ddaa6fc077c15e83c7076835a530b716e4a3
Prevent GetThreadContext failure (Windows)
(a cherry-pick of commits 3f39ea8ab3699da from 'unity-master')

Calls to GetThreadContext may fail.  Work around this by putting
access in suspend/resume loop to advance thread past problematic areas
where suspend fails.  Capture context in per thread structure at
suspend time rather than retreiving it during the push logic.

* include/private/gcconfig.h [(I386 || X86_64) && (CYGWIN32 || MSWIN32)]
(RETRY_GET_THREAD_CONTEXT): Define macro.
* win32_threads.c [RETRY_GET_THREAD_CONTEXT]
(MAX_SUSPEND_THREAD_RETRIES): Likewise.
* include/private/gcconfig.h [NO_RETRY_GET_THREAD_CONTEXT]
(RETRY_GET_THREAD_CONTEXT): Undefine macro (for test purposes).
* win32_threads.c [RETRY_GET_THREAD_CONTEXT] (GC_Thread_Rep): Add
saved_context field; add comment.
* win32_threads.c [RETRY_GET_THREAD_CONTEXT] (GC_suspend): Define
retry_cnt local variable; set ContextFlags and call GetThreadContext()
after invocation of SuspendThread(); call ResumeThread() and proceed to
SuspendThread() if GetThreadContext() failed (the limit of iterations
is MAX_SUSPEND_THREAD_RETRIES); call Sleep(0) after ResumeThread() or
failed SuspendThread() except for the first 2 iterations.
* win32_threads.c [RETRY_GET_THREAD_CONTEXT] (GC_push_stack_for):
Declare pcontext local variable (which refers to thread->saved_context);
define context as a macro (to *pcontext) instead of a local variable;
add comment; do not set ContextFlags and do not call GetThreadContext();
undefine context after last use of PUSHn().
include/private/gcconfig.h
win32_threads.c