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