Guard against threads joining twice. After a pthread_join() call the handle becomes invalid or could be recycled by another thread, leading to undefined behavior when attempting to join it again. Also, on Windows the handle has to be closed to free it. Bug b/34883464 Change-Id: Ib20d0539b6b46e331c6378b3a9f0c2a334d34892 Reviewed-on: https://swiftshader-review.googlesource.com/8612 Reviewed-by: Alexis Hétu <sugoi@google.com> Reviewed-by: Nicolas Capens <capn@google.com> Tested-by: Nicolas Capens <capn@google.com>
diff --git a/src/Common/Thread.cpp b/src/Common/Thread.cpp index 9a7b342..df9a0b7 100644 --- a/src/Common/Thread.cpp +++ b/src/Common/Thread.cpp
@@ -22,9 +22,9 @@ Entry entry = {threadFunction, parameters, &init}; #if defined(_WIN32) - handle = CreateThread(0, 1024 * 1024, startFunction, &entry, 0, 0); + handle = CreateThread(NULL, 1024 * 1024, startFunction, &entry, 0, NULL); #else - pthread_create(&handle, 0, startFunction, &entry); + pthread_create(&handle, NULL, startFunction, &entry); #endif init.wait(); @@ -37,11 +37,17 @@ void Thread::join() { - #if defined(_WIN32) - WaitForSingleObject(handle, INFINITE); - #else - pthread_join(handle, 0); - #endif + if(!hasJoined) + { + #if defined(_WIN32) + WaitForSingleObject(handle, INFINITE); + CloseHandle(handle); + #else + pthread_join(handle, NULL); + #endif + + hasJoined = true; + } } #if defined(_WIN32) @@ -58,17 +64,17 @@ Entry entry = *(Entry*)parameters; entry.init->signal(); entry.threadFunction(entry.threadParameters); - return 0; + return nullptr; } #endif Event::Event() { #if defined(_WIN32) - handle = CreateEvent(0, FALSE, FALSE, 0); + handle = CreateEvent(NULL, FALSE, FALSE, NULL); #else - pthread_cond_init(&handle, 0); - pthread_mutex_init(&mutex, 0); + pthread_cond_init(&handle, NULL); + pthread_mutex_init(&mutex, NULL); signaled = false; #endif }
diff --git a/src/Common/Thread.hpp b/src/Common/Thread.hpp index deb8b29..8f6443e 100644 --- a/src/Common/Thread.hpp +++ b/src/Common/Thread.hpp
@@ -70,6 +70,8 @@ static void *startFunction(void *parameters); pthread_t handle; #endif + + bool hasJoined = false; }; class Event