Free thread-local storage implicitly on thread termination.

Some applications may not call eglReleaseThread() before terminating a
thread, which can cause a minor memory leak. pthread_key_create()
supports specifying a destructor callback to implicitly free the
thread-local storage on thread termination. On Windows we use the
DLL_THREAD_DETACH signal to free it explicitly. This change also
simplifies TLS management by removing the ability to set a new value.

Bug swiftshader:80

Change-Id: I249ca519c1c9ab722e570516d0931cb17ea081bb
Reviewed-on: https://swiftshader-review.googlesource.com/12068
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Common/Thread.hpp b/src/Common/Thread.hpp
index 3b9e674..87b90d1 100644
--- a/src/Common/Thread.hpp
+++ b/src/Common/Thread.hpp
@@ -28,6 +28,8 @@
 	#define TLS_OUT_OF_INDEXES (pthread_key_t)(~0)
 #endif
 
+#include <stdlib.h>
+
 namespace sw
 {
 	class Event;
@@ -52,8 +54,9 @@
 
 		static LocalStorageKey allocateLocalStorageKey();
 		static void freeLocalStorageKey(LocalStorageKey key);
-		static void setLocalStorage(LocalStorageKey key, void *value);
+		static void *allocateLocalStorage(LocalStorageKey key, size_t size);
 		static void *getLocalStorage(LocalStorageKey key);
+		static void freeLocalStorage(LocalStorageKey key);
 
 	private:
 		struct Entry
@@ -135,7 +138,7 @@
 			return TlsAlloc();
 		#else
 			LocalStorageKey key;
-			pthread_key_create(&key, NULL);
+			pthread_key_create(&key, free);
 			return key;
 		#endif
 	}
@@ -149,16 +152,24 @@
 		#endif
 	}
 
-	inline void Thread::setLocalStorage(LocalStorageKey key, void *value)
+	inline void *Thread::allocateLocalStorage(LocalStorageKey key, size_t size)
 	{
+		if(key == TLS_OUT_OF_INDEXES)
+		{
+			return nullptr;
+		}
+
+		freeLocalStorage(key);
+
+		void *storage = malloc(size);
+
 		#if defined(_WIN32)
-			TlsSetValue(key, value);
+			TlsSetValue(key, storage);
 		#else
-			if(key != TLS_OUT_OF_INDEXES)   // Avoid undefined behavior.
-			{
-				pthread_setspecific(key, value);
-			}
+			pthread_setspecific(key, storage);
 		#endif
+
+		return storage;
 	}
 
 	inline void *Thread::getLocalStorage(LocalStorageKey key)
@@ -175,6 +186,17 @@
 		#endif
 	}
 
+	inline void Thread::freeLocalStorage(LocalStorageKey key)
+	{
+		free(getLocalStorage(key));
+
+		#if defined(_WIN32)
+			TlsSetValue(key, nullptr);
+		#else
+			pthread_setspecific(key, nullptr);
+		#endif
+	}
+
 	inline void Event::signal()
 	{
 		#if defined(_WIN32)
diff --git a/src/OpenGL/libEGL/main.cpp b/src/OpenGL/libEGL/main.cpp
index 3a8d1ce..b953e4b 100644
--- a/src/OpenGL/libEGL/main.cpp
+++ b/src/OpenGL/libEGL/main.cpp
@@ -48,14 +48,7 @@
 		currentTLS = sw::Thread::allocateLocalStorageKey();
 	}
 
-	Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);
-
-	if(!current)
-	{
-		current = new Current;
-
-		sw::Thread::setLocalStorage(currentTLS, current);
-	}
+	Current *current = (Current*)sw::Thread::allocateLocalStorage(currentTLS, sizeof(Current));
 
 	current->error = EGL_SUCCESS;
 	current->API = EGL_OPENGL_ES_API;
@@ -72,8 +65,7 @@
 
 	eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
 
-	delete (Current*)sw::Thread::getLocalStorage(currentTLS);
-	sw::Thread::setLocalStorage(currentTLS, nullptr);
+	sw::Thread::freeLocalStorage(currentTLS);
 }
 
 CONSTRUCTOR void attachProcess()