Attached patch adds some error checking to the thread locking stuff in
libpq. Previously, if thread locking failed for some reason, we would
just fall through and do things without locking. This patch makes us
abort() instead. It's not the greatest thing probably, but our API
doesn't let us pass back return values...

Comments?

//Magnus
Index: src/interfaces/libpq/fe-connect.c
===================================================================
RCS file: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v
retrieving revision 1.357
diff -c -r1.357 fe-connect.c
*** src/interfaces/libpq/fe-connect.c	31 Mar 2008 02:43:14 -0000	1.357
--- src/interfaces/libpq/fe-connect.c	7 May 2008 19:17:39 -0000
***************
*** 3835,3848 ****
  		while (InterlockedExchange(&mutex_initlock, 1) == 1)
  			 /* loop, another thread own the lock */ ;
  		if (singlethread_lock == NULL)
! 			pthread_mutex_init(&singlethread_lock, NULL);
  		InterlockedExchange(&mutex_initlock, 0);
  	}
  #endif
  	if (acquire)
! 		pthread_mutex_lock(&singlethread_lock);
  	else
! 		pthread_mutex_unlock(&singlethread_lock);
  #endif
  }
  
--- 3835,3867 ----
  		while (InterlockedExchange(&mutex_initlock, 1) == 1)
  			 /* loop, another thread own the lock */ ;
  		if (singlethread_lock == NULL)
! 		{
! 			if (pthread_mutex_init(&singlethread_lock, NULL))
! 				/*
! 				 * We have no way to pass back error values, but we don't want to
! 				 * proceed without having any locking. abort() seems to be the least
! 				 * evil thing to do here.
! 				 */
! 				abort();
! 		}
  		InterlockedExchange(&mutex_initlock, 0);
  	}
  #endif
  	if (acquire)
! 	{
! 		if (pthread_mutex_lock(&singlethread_lock))
! 			/* 
! 			 * We have no way to pass back error values, but we don't want to proceed
! 			 * without having any locking. abort() seems to be the least evil thing
! 			 * to do here.
! 			 */
! 			abort();
! 	}
  	else
! 	{
! 		if (pthread_mutex_unlock(&singlethread_lock))
! 			abort();
! 	}
  #endif
  }
  
Index: src/interfaces/libpq/fe-secure.c
===================================================================
RCS file: /cvsroot/pgsql/src/interfaces/libpq/fe-secure.c,v
retrieving revision 1.104
diff -c -r1.104 fe-secure.c
*** src/interfaces/libpq/fe-secure.c	31 Mar 2008 02:43:14 -0000	1.104
--- src/interfaces/libpq/fe-secure.c	7 May 2008 19:17:39 -0000
***************
*** 796,807 ****
  pq_lockingcallback(int mode, int n, const char *file, int line)
  {
  	if (mode & CRYPTO_LOCK)
! 		pthread_mutex_lock(&pq_lockarray[n]);
  	else
! 		pthread_mutex_unlock(&pq_lockarray[n]);
  }
  #endif   /* ENABLE_THREAD_SAFETY */
  
  static int
  init_ssl_system(PGconn *conn)
  {
--- 796,816 ----
  pq_lockingcallback(int mode, int n, const char *file, int line)
  {
  	if (mode & CRYPTO_LOCK)
! 	{
! 		if (pthread_mutex_lock(&pq_lockarray[n]))
! 			abort();
! 	}
  	else
! 	{
! 		if (pthread_mutex_unlock(&pq_lockarray[n]))
! 			abort();
! 	}
  }
  #endif   /* ENABLE_THREAD_SAFETY */
  
+ /*
+  * Also see similar code in fe-connect.c, default_threadlock()
+  */
  static int
  init_ssl_system(PGconn *conn)
  {
***************
*** 817,827 ****
  		while (InterlockedExchange(&mutex_initlock, 1) == 1)
  			 /* loop, another thread own the lock */ ;
  		if (init_mutex == NULL)
! 			pthread_mutex_init(&init_mutex, NULL);
  		InterlockedExchange(&mutex_initlock, 0);
  	}
  #endif
! 	pthread_mutex_lock(&init_mutex);
  
  	if (pq_initssllib && pq_lockarray == NULL)
  	{
--- 826,840 ----
  		while (InterlockedExchange(&mutex_initlock, 1) == 1)
  			 /* loop, another thread own the lock */ ;
  		if (init_mutex == NULL)
! 		{
! 			if (pthread_mutex_init(&init_mutex, NULL))
! 				return -1;
! 		}
  		InterlockedExchange(&mutex_initlock, 0);
  	}
  #endif
! 	if (pthread_mutex_lock(&init_mutex))
! 		return -1;
  
  	if (pq_initssllib && pq_lockarray == NULL)
  	{
***************
*** 836,842 ****
  			return -1;
  		}
  		for (i = 0; i < CRYPTO_num_locks(); i++)
! 			pthread_mutex_init(&pq_lockarray[i], NULL);
  
  		CRYPTO_set_locking_callback(pq_lockingcallback);
  	}
--- 849,858 ----
  			return -1;
  		}
  		for (i = 0; i < CRYPTO_num_locks(); i++)
! 		{
! 			if (pthread_mutex_init(&pq_lockarray[i], NULL))
! 				return -1;
! 		}
  
  		CRYPTO_set_locking_callback(pq_lockingcallback);
  	}
Index: src/interfaces/libpq/pthread-win32.c
===================================================================
RCS file: /cvsroot/pgsql/src/interfaces/libpq/pthread-win32.c,v
retrieving revision 1.15
diff -c -r1.15 pthread-win32.c
*** src/interfaces/libpq/pthread-win32.c	1 Jan 2008 19:46:00 -0000	1.15
--- src/interfaces/libpq/pthread-win32.c	7 May 2008 19:17:39 -0000
***************
*** 32,51 ****
  	return NULL;
  }
  
! void
  pthread_mutex_init(pthread_mutex_t *mp, void *attr)
  {
  	*mp = CreateMutex(0, 0, 0);
  }
  
! void
  pthread_mutex_lock(pthread_mutex_t *mp)
  {
! 	WaitForSingleObject(*mp, INFINITE);
  }
  
! void
  pthread_mutex_unlock(pthread_mutex_t *mp)
  {
! 	ReleaseMutex(*mp);
  }
--- 32,58 ----
  	return NULL;
  }
  
! int
  pthread_mutex_init(pthread_mutex_t *mp, void *attr)
  {
  	*mp = CreateMutex(0, 0, 0);
+ 	if (*mp == NULL)
+ 		return 1;
+ 	return 0;
  }
  
! int
  pthread_mutex_lock(pthread_mutex_t *mp)
  {
! 	if (WaitForSingleObject(*mp, INFINITE) != WAIT_OBJECT_0)
! 		return 1;
! 	return 0;
  }
  
! int
  pthread_mutex_unlock(pthread_mutex_t *mp)
  {
! 	if (!ReleaseMutex(*mp))
! 		return 1;
! 	return 0;
  }
Index: src/port/pthread-win32.h
===================================================================
RCS file: /cvsroot/pgsql/src/port/pthread-win32.h,v
retrieving revision 1.2
diff -c -r1.2 pthread-win32.h
*** src/port/pthread-win32.h	18 Apr 2007 08:32:40 -0000	1.2
--- src/port/pthread-win32.h	7 May 2008 19:17:39 -0000
***************
*** 10,19 ****
  void		pthread_setspecific(pthread_key_t, void *);
  void	   *pthread_getspecific(pthread_key_t);
  
! void		pthread_mutex_init(pthread_mutex_t *, void *attr);
! void		pthread_mutex_lock(pthread_mutex_t *);
  
  /* blocking */
! void		pthread_mutex_unlock(pthread_mutex_t *);
  
  #endif
--- 10,19 ----
  void		pthread_setspecific(pthread_key_t, void *);
  void	   *pthread_getspecific(pthread_key_t);
  
! int			pthread_mutex_init(pthread_mutex_t *, void *attr);
! int			pthread_mutex_lock(pthread_mutex_t *);
  
  /* blocking */
! int			pthread_mutex_unlock(pthread_mutex_t *);
  
  #endif
-- 
Sent via pgsql-patches mailing list (pgsql-patches@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-patches

Reply via email to