未验证 提交 4293dbb8 编写于 作者: J Jonathan Chambers 提交者: GitHub

Merge pull request #1036 from Unity-Technologies/unity-trunk-fix-getthreadcontext

Add loop to avoid assert from failing call to GetThreadContext (case …
......@@ -50,6 +50,7 @@ struct GC_thread_Rep {
/* 0 ==> entry not valid. */
/* !in_use ==> stack_base == 0 */
GC_bool suspended;
CONTEXT saved_context;
# ifdef CYGWIN32
void *status; /* hold exit value until join in case it's a pointer */
......@@ -286,6 +287,7 @@ void GC_stop_world()
{
DWORD thread_id = GetCurrentThreadId();
int i;
int iterations = 0;
if (!GC_thr_initialized) ABORT("GC_stop_world() called before GC_thr_init()");
......@@ -300,6 +302,7 @@ void GC_stop_world()
/* SuspendThread will fail if thread is running kernel code */
while (SuspendThread(thread_table[i].handle) == (DWORD)-1)
Sleep(10);
thread_table[i].suspended = TRUE;
# else
/* Apparently the Windows 95 GetOpenFileName call creates */
/* a thread that does not properly get cleaned up, and */
......@@ -318,17 +321,29 @@ void GC_stop_world()
# endif
continue;
}
if (SuspendThread(thread_table[i].handle) == (DWORD)-1) {
thread_table[i].stack_base = 0; /* prevent stack from being pushed */
# ifndef CYGWIN32
/* this breaks pthread_join on Cygwin, which is guaranteed to */
/* only see user pthreads */
thread_table[i].in_use = FALSE;
CloseHandle(thread_table[i].handle);
# endif
while (InterlockedCompareExchange (&thread_table[i].in_use, 0, 0)) {
DWORD res;
do {
res = SuspendThread (thread_table[i].handle);
} while (res == -1);
thread_table[i].saved_context.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
if (GetThreadContext (thread_table[i].handle, &thread_table[i].saved_context)) {
thread_table[i].suspended = TRUE;
break; /* success case break out of loop */
}
/* resume thread and try to suspend in better location */
if (ResumeThread (thread_table[i].handle) == (DWORD)-1)
ABORT ("ResumeThread failed");
/* after a million tries something must be wrong */
if (iterations++ == 1000 * 1000)
ABORT ("SuspendThread loop failed");
}
# endif
thread_table[i].suspended = TRUE;
}
# ifndef CYGWIN32
LeaveCriticalSection(&GC_write_cs);
......@@ -415,10 +430,8 @@ void GC_push_all_stacks()
continue;
}
else {
CONTEXT context;
context.ContextFlags = CONTEXT_INTEGER|CONTEXT_CONTROL;
if (!GetThreadContext(thread_table[i].handle, &context))
ABORT("GetThreadContext failed");
/* we cache context when suspending the thread since it may require looping */
CONTEXT context = thread_table[i].saved_context;
/* Push all registers that might point into the heap. Frame */
/* pointer registers are included in case client code was */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册