*** src/backend/libpq/be-secure.c
--- src/backend/libpq/be-secure.c
***************
*** 831,851 **** initialize_SSL(void)
  	}
  }
  
- #ifdef NOT_USED
- /*
-  *	Destroy global SSL context
-  */
- static void
- destroy_global_SSL(void)
- {
- 	if (SSL_context)
- 	{
- 		SSL_CTX_free(SSL_context);
- 		SSL_context = NULL;
- 	}
- }
- #endif
- 
  /*
   *	Attempt to negotiate SSL connection.
   */
--- 831,836 ----
*** src/interfaces/libpq/fe-secure.c
--- src/interfaces/libpq/fe-secure.c
***************
*** 92,98 **** static int	client_cert_cb(SSL *, X509 **, EVP_PKEY **);
  static int	init_ssl_system(PGconn *conn);
  static void destroy_ssl_system(void);
  static int	initialize_SSL(PGconn *);
! static void destroy_SSL(void);
  static PostgresPollingStatusType open_client_SSL(PGconn *);
  static void close_SSL(PGconn *);
  static char *SSLerrmessage(void);
--- 92,98 ----
  static int	init_ssl_system(PGconn *conn);
  static void destroy_ssl_system(void);
  static int	initialize_SSL(PGconn *);
! static void destroySSL(void);
  static PostgresPollingStatusType open_client_SSL(PGconn *);
  static void close_SSL(PGconn *);
  static char *SSLerrmessage(void);
***************
*** 199,205 **** void
  pqsecure_destroy(void)
  {
  #ifdef USE_SSL
! 	destroy_SSL();
  #endif
  }
  
--- 199,205 ----
  pqsecure_destroy(void)
  {
  #ifdef USE_SSL
! 	destroySSL();
  #endif
  }
  
***************
*** 747,752 **** client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
--- 747,755 ----
  }
  
  #ifdef ENABLE_THREAD_SAFETY
+ /*
+  *	Callback functions for OpenSSL internal locking
+  */
  
  static unsigned long
  pq_threadidcallback(void)
***************
*** 778,790 **** pq_lockingcallback(int mode, int n, const char *file, int line)
  #endif   /* ENABLE_THREAD_SAFETY */
  
  /*
!  * Also see similar code in fe-connect.c, default_threadlock()
   */
  static int
  init_ssl_system(PGconn *conn)
  {
  #ifdef ENABLE_THREAD_SAFETY
  #ifdef WIN32
  	if (ssl_config_mutex == NULL)
  	{
  		while (InterlockedExchange(&win32_ssl_create_mutex, 1) == 1)
--- 781,802 ----
  #endif   /* ENABLE_THREAD_SAFETY */
  
  /*
!  * Initialize SSL system. In threadsafe mode, this includes setting
!  * up OpenSSL callback functions to do thread locking.
!  *
!  * If the caller has told us (through PQinitSSL) that he's taking care
!  * of SSL, we expect that callbacks are already set, and won't try to
!  * override it.
!  *
!  * The conn parameter is only used to be able to pass back an error
!  * message - no connection local setup is made.
   */
  static int
  init_ssl_system(PGconn *conn)
  {
  #ifdef ENABLE_THREAD_SAFETY
  #ifdef WIN32
+ 	/* Also see similar code in fe-connect.c, default_threadlock() */
  	if (ssl_config_mutex == NULL)
  	{
  		while (InterlockedExchange(&win32_ssl_create_mutex, 1) == 1)
***************
*** 802,811 **** init_ssl_system(PGconn *conn)
  
  	if (pq_initssllib)
  	{
  		if (pq_lockarray == NULL)
  		{
  			int i;
! 			
  			pq_lockarray = malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks());
  			if (!pq_lockarray)
  			{
--- 814,827 ----
  
  	if (pq_initssllib)
  	{
+ 		/*
+ 		 * If necessary, set up an array to hold locks for OpenSSL. OpenSSL will
+ 		 * tell us how big to make this array.
+ 		 */
  		if (pq_lockarray == NULL)
  		{
  			int i;
! 
  			pq_lockarray = malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks());
  			if (!pq_lockarray)
  			{
***************
*** 823,829 **** init_ssl_system(PGconn *conn)
  				}
  			}
  		}
! 		
  		if (ssl_open_connections++ == 0)
  		{
  			/* These are only required for threaded SSL applications */
--- 839,845 ----
  				}
  			}
  		}
! 
  		if (ssl_open_connections++ == 0)
  		{
  			/* These are only required for threaded SSL applications */
***************
*** 858,863 **** init_ssl_system(PGconn *conn)
--- 874,880 ----
  			return -1;
  		}
  	}
+ 
  #ifdef ENABLE_THREAD_SAFETY
  	pthread_mutex_unlock(&ssl_config_mutex);
  #endif
***************
*** 870,904 **** init_ssl_system(PGconn *conn)
   *	SSL used by other parts of the system.  For this reason,
   *	we unregister the SSL callback functions when the last libpq
   *	connection is closed.
   */
  static void
  destroy_ssl_system(void)
  {
  #ifdef ENABLE_THREAD_SAFETY
! 	/* Assume mutex is already created */
  	if (pthread_mutex_lock(&ssl_config_mutex))
  		return;
  
  	if (pq_initssllib)
  	{
- 		/*
- 		 *	We never free pq_lockarray, which means we leak memory on
- 		 *	repeated loading/unloading of this library.
- 		 */
- 
  		if (ssl_open_connections > 0)
  			--ssl_open_connections;
  
  		if (ssl_open_connections == 0)
  		{
! 			/*
! 			 *	We need to unregister the SSL callbacks on last connection
! 			 *	close because the libpq shared library might be unloaded,
! 			 *	and once it is, callbacks must be removed to prevent them
! 			 *	from being called by other SSL code.
! 			 */
  			CRYPTO_set_locking_callback(NULL);
  			CRYPTO_set_id_callback(NULL);
  		}
  	}
  
--- 887,925 ----
   *	SSL used by other parts of the system.  For this reason,
   *	we unregister the SSL callback functions when the last libpq
   *	connection is closed.
+  *
+  *	Callbacks are only set when we're compiled in threadsafe mode, so
+  *	we only need to remove them in this case.
   */
  static void
  destroy_ssl_system(void)
  {
  #ifdef ENABLE_THREAD_SAFETY
! 	/* Mutex is created in initialize_ssl_system() */
  	if (pthread_mutex_lock(&ssl_config_mutex))
  		return;
  
  	if (pq_initssllib)
  	{
  		if (ssl_open_connections > 0)
  			--ssl_open_connections;
  
  		if (ssl_open_connections == 0)
  		{
! 			/* No connections left, unregister all callbacks */
  			CRYPTO_set_locking_callback(NULL);
  			CRYPTO_set_id_callback(NULL);
+ 
+ 			/*
+ 			 * We don't free the lock array. If we get another connection
+ 			 * from the same caller, we will just re-use it with the existing
+ 			 * mutexes.
+ 			 *
+ 			 * This means we leak a little memory on repeated load/unload
+ 			 * of the library.
+ 			 */
+ 			free(pqlockarray);
+ 			pqlockarray = NULL;
  		}
  	}
  
***************
*** 908,914 **** destroy_ssl_system(void)
  }
  
  /*
!  *	Initialize global SSL context.
   */
  static int
  initialize_SSL(PGconn *conn)
--- 929,935 ----
  }
  
  /*
!  *	Initialize SSL context.
   */
  static int
  initialize_SSL(PGconn *conn)
***************
*** 996,1021 **** initialize_SSL(PGconn *conn)
  }
  
  static void
! destroy_SSL(void)
  {
  	destroy_ssl_system();
  }
  
- #ifdef NOT_USED
- /*
-  *	Destroy global SSL context
-  */
- static void
- destroy_global_SSL(void)
- {
- 	if (SSL_context)
- 	{
- 		SSL_CTX_free(SSL_context);
- 		SSL_context = NULL;
- 	}
- }
- #endif
- 
  /*
   *	Attempt to negotiate SSL connection.
   */
--- 1017,1027 ----
  }
  
  static void
! destroySSL(void)
  {
  	destroy_ssl_system();
  }
  
  /*
   *	Attempt to negotiate SSL connection.
   */
