From 6aafcece307197d7f453b081093b35c5ba00c821 Mon Sep 17 00:00:00 2001
From: Christian Ullrich <chris@chrullrich.net>
Date: Wed, 16 Nov 2016 17:02:27 +0100
Subject: [PATCH] Avoid a possible crash.

Although PostgreSQL itself does not use multithreading, there are always a
number of threads in a process on Windows. If one of them causes a CRT to
unload at the wrong time, we can crash in the _putenv() call. Fix by
keeping our own reference to the loaded DLL as long as we need.

Per suggestion from Noah Misch.
---
 src/port/win32env.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/port/win32env.c b/src/port/win32env.c
index 25eed06..5b594e3 100644
--- a/src/port/win32env.c
+++ b/src/port/win32env.c
@@ -102,14 +102,20 @@ pgwin32_putenv(const char *envval)
 	 */
 	for (i = 0; modulenames[i]; i++)
 	{
-		HMODULE hmodule = GetModuleHandle(modulenames[i]);
-		if (hmodule)
+		/*
+		 * Make sure nothing else unloads the DLL while we are using it
+		 * by creating our own reference to it.
+		 */
+		HMODULE hmodule = NULL;
+		BOOL res = GetModuleHandleEx(0, modulenames[i], &hmodule);
+		if (res != 0 && hmodule != NULL)
 		{
 			PUTENVPROC putenvFunc = (PUTENVPROC) GetProcAddress(hmodule, "_putenv");
 			if (putenvFunc)
 			{
 				putenvFunc(envval);
 			}
+			FreeLibrary(hmodule);
 		}
 	}
 #endif   /* _MSC_VER */
-- 
2.10.2.windows.1

