From 96b171903d5d52ca46b46bc3f73f13978705eae5 Mon Sep 17 00:00:00 2001
From: Magnus Hagander <magnus@hagander.net>
Date: Thu, 29 Mar 2007 15:30:52 +0000
Subject: [PATCH] Make ECPG regression tests use native threading instead of
 pthreads, now that  ecpglib supports it. Change configure (patch from Bruce)
 and msvc build system to no longer require  pthreads on win32, since all
 parts of postgresql can be thread-safe using the  native platform functions.

---
 configure                                     | 37 +++++++++-
 configure.in                                  | 14 +++-
 doc/src/sgml/install-win32.sgml               | 11 +--
 .../ecpg/test/expected/thread-thread.c        | 72 +++++++++++--------
 .../test/expected/thread-thread_implicit.c    | 72 +++++++++++--------
 src/interfaces/ecpg/test/thread/thread.pgc    | 18 ++++-
 .../ecpg/test/thread/thread_implicit.pgc      | 18 ++++-
 src/tools/msvc/Mkvcbuild.pm                   | 56 ++++++---------
 src/tools/msvc/Project.pm                     |  7 +-
 src/tools/msvc/Solution.pm                    | 10 +--
 src/tools/msvc/config.pl                      |  1 -
 11 files changed, 201 insertions(+), 115 deletions(-)

diff --git a/configure b/configure
index 72d66b988aa..c5a20b1e122 100755
--- a/configure
+++ b/configure
@@ -3683,6 +3683,7 @@ IFS=$ac_save_IFS
 #
 echo "$as_me:$LINENO: checking allow thread-safe client libraries" >&5
 echo $ECHO_N "checking allow thread-safe client libraries... $ECHO_C" >&6
+if test "$PORTNAME" != "win32"; then
 
 pgac_args="$pgac_args enable_thread_safety"
 
@@ -3709,6 +3710,36 @@ else
 
 fi;
 
+else
+# Win32 should always use threads
+
+pgac_args="$pgac_args enable_thread_safety"
+
+# Check whether --enable-thread-safety or --disable-thread-safety was given.
+if test "${enable_thread_safety+set}" = set; then
+  enableval="$enable_thread_safety"
+
+  case $enableval in
+    yes)
+      :
+      ;;
+    no)
+      :
+      ;;
+    *)
+      { { echo "$as_me:$LINENO: error: no argument expected for --enable-thread-safety option" >&5
+echo "$as_me: error: no argument expected for --enable-thread-safety option" >&2;}
+   { (exit 1); exit 1; }; }
+      ;;
+  esac
+
+else
+  enable_thread_safety=yes
+
+fi;
+
+fi
+
 
 pgac_args="$pgac_args enable_thread_safety_force"
 
@@ -16701,8 +16732,8 @@ fi
 # For each platform, we need to know about any special compile and link
 # libraries, and whether the normal C function names are thread-safe.
 # See the comment at the top of src/port/thread.c for more information.
-#
-if test "$enable_thread_safety" = yes; then
+# WIN32 doesn't need the pthread tests;  it always uses threads
+if test "$enable_thread_safety" = yes -a "$PORTNAME" != "win32"; then
 
 
 
@@ -17236,6 +17267,7 @@ _LIBS="$LIBS"
 CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
 LIBS="$LIBS $PTHREAD_LIBS"
 
+if test "$PORTNAME" != "win32"; then
 if test "${ac_cv_header_pthread_h+set}" = set; then
   echo "$as_me:$LINENO: checking for pthread.h" >&5
 echo $ECHO_N "checking for pthread.h... $ECHO_C" >&6
@@ -17382,6 +17414,7 @@ echo "$as_me: error: pthread.h not found, required for --enable-thread-safety" >
 fi
 
 
+fi
 
 
 
diff --git a/configure.in b/configure.in
index 194c56a5671..03511fbd464 100644
--- a/configure.in
+++ b/configure.in
@@ -1,5 +1,5 @@
 dnl Process this file with autoconf to produce a configure script.
-dnl $PostgreSQL: pgsql/configure.in,v 1.506 2007/03/26 21:30:56 momjian Exp $
+dnl $PostgreSQL: pgsql/configure.in,v 1.507 2007/03/29 15:30:51 mha Exp $
 dnl
 dnl Developers, please strive to achieve this order:
 dnl
@@ -416,7 +416,13 @@ IFS=$ac_save_IFS
 # Enable thread-safe client libraries
 #
 AC_MSG_CHECKING([allow thread-safe client libraries])
+if test "$PORTNAME" != "win32"; then
 PGAC_ARG_BOOL(enable, thread-safety, no, [  --enable-thread-safety  make client libraries thread-safe])
+else
+# Win32 should always use threads
+PGAC_ARG_BOOL(enable, thread-safety, yes, [  --enable-thread-safety  make client libraries thread-safe])
+fi
+
 PGAC_ARG_BOOL(enable, thread-safety-force, no, [  --enable-thread-safety-force  force thread-safety in spite of thread test failure])
 if test "$enable_thread_safety" = yes -o \
         "$enable_thread_safety_force" = yes; then
@@ -1108,8 +1114,8 @@ AC_FUNC_FSEEKO
 # For each platform, we need to know about any special compile and link
 # libraries, and whether the normal C function names are thread-safe.
 # See the comment at the top of src/port/thread.c for more information.
-#
-if test "$enable_thread_safety" = yes; then
+# WIN32 doesn't need the pthread tests;  it always uses threads
+if test "$enable_thread_safety" = yes -a "$PORTNAME" != "win32"; then
 ACX_PTHREAD	# set thread flags
 
 # Some platforms use these, so just defineed them.  They can't hurt if they
@@ -1137,7 +1143,9 @@ _LIBS="$LIBS"
 CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
 LIBS="$LIBS $PTHREAD_LIBS"
 
+if test "$PORTNAME" != "win32"; then
 AC_CHECK_HEADER(pthread.h, [], [AC_MSG_ERROR([pthread.h not found, required for --enable-thread-safety])])
+fi
 
 AC_CHECK_FUNCS([strerror_r getpwuid_r gethostbyname_r])
 
diff --git a/doc/src/sgml/install-win32.sgml b/doc/src/sgml/install-win32.sgml
index 4244a0e6fb8..f2fbdb8440f 100644
--- a/doc/src/sgml/install-win32.sgml
+++ b/doc/src/sgml/install-win32.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/install-win32.sgml,v 1.37 2007/03/24 22:16:49 mha Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/install-win32.sgml,v 1.38 2007/03/29 15:30:52 mha Exp $ -->
 
 <chapter id="install-win32">
  <title>Installation on <productname>Windows</productname></title>
@@ -161,15 +161,6 @@
      </para></listitem>
     </varlistentry>
 
-    <varlistentry>
-     <term><productname>pthreads</productname></term>
-     <listitem><para>
-      Required for building the <application>ECPG</application> libraries.
-      Binaries can be downloaded from
-      <ulink url="ftp://sources.redhat.com/pub/pthreads-win32"></>.
-     </para></listitem>
-    </varlistentry>
-
     <varlistentry>
      <term><productname>Python</productname></term>
      <listitem><para>
diff --git a/src/interfaces/ecpg/test/expected/thread-thread.c b/src/interfaces/ecpg/test/expected/thread-thread.c
index 5011640b327..9555a79bfa5 100644
--- a/src/interfaces/ecpg/test/expected/thread-thread.c
+++ b/src/interfaces/ecpg/test/expected/thread-thread.c
@@ -23,7 +23,11 @@ main(void)
 	return 0;
 }
 #else
+#ifndef WIN32
 #include <pthread.h>
+#else
+#include <windows.h>
+#endif
 
 
 #line 1 "regression.h"
@@ -33,7 +37,7 @@ main(void)
 
 
 
-#line 18 "thread.pgc"
+#line 22 "thread.pgc"
 
 
 void *test_thread(void *arg);
@@ -43,15 +47,19 @@ int iterations = 20;
 
 int main(int argc, char *argv[])
 {
+#ifndef WIN32
   pthread_t *threads;
+#else
+  HANDLE *threads;
+#endif
   int n;
   /* exec sql begin declare section */
    
   
-#line 30 "thread.pgc"
+#line 38 "thread.pgc"
  int  l_rows    ;
 /* exec sql end declare section */
-#line 31 "thread.pgc"
+#line 39 "thread.pgc"
 
 
  /* Do not switch on debug output for regression tests. The threads get executed in
@@ -60,26 +68,26 @@ int main(int argc, char *argv[])
 
   /* setup test_thread table */
   { ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0); }
-#line 38 "thread.pgc"
+#line 46 "thread.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, "drop table test_thread ", ECPGt_EOIT, ECPGt_EORT);}
-#line 39 "thread.pgc"
+#line 47 "thread.pgc"
  /* DROP might fail */
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 40 "thread.pgc"
+#line 48 "thread.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, "create  table test_thread ( tstamp timestamp    not null default cast( timeofday () as timestamp   ) , thread TEXT    not null , iteration integer   not null , primary key( thread , iteration )   )    ", ECPGt_EOIT, ECPGt_EORT);}
-#line 45 "thread.pgc"
+#line 53 "thread.pgc"
 
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 46 "thread.pgc"
+#line 54 "thread.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
-#line 47 "thread.pgc"
+#line 55 "thread.pgc"
 
 
   /* create, and start, threads */
-  threads = calloc(nthreads, sizeof(pthread_t));
+  threads = calloc(nthreads, sizeof(threads[0]));
   if( threads == NULL )
     {
       fprintf(stderr, "Cannot alloc memory\n");
@@ -87,30 +95,38 @@ int main(int argc, char *argv[])
     }
   for( n = 0; n < nthreads; n++ )
     {
+#ifndef WIN32
       pthread_create(&threads[n], NULL, test_thread, (void *) (n + 1));
+#else
+      threads[n] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)test_thread, (void *) (n + 1), 0, NULL);
+#endif
     }
 
   /* wait for thread completion */
+#ifndef WIN32
   for( n = 0; n < nthreads; n++ )
     {
       pthread_join(threads[n], NULL);
     }
+#else
+  WaitForMultipleObjects(nthreads, threads, TRUE, INFINITE);
+#endif
   free(threads);
 
   /* and check results */
   { ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0); }
-#line 69 "thread.pgc"
+#line 85 "thread.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, "select  count (*)  from test_thread   ", ECPGt_EOIT, 
 	ECPGt_int,&(l_rows),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
-#line 70 "thread.pgc"
+#line 86 "thread.pgc"
 
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 71 "thread.pgc"
+#line 87 "thread.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
-#line 72 "thread.pgc"
+#line 88 "thread.pgc"
 
   if( l_rows == (nthreads * iterations) )
     printf("Success.\n");
@@ -127,25 +143,25 @@ void *test_thread(void *arg)
     
    
   
-#line 85 "thread.pgc"
+#line 101 "thread.pgc"
  int  l_i    ;
  
-#line 86 "thread.pgc"
+#line 102 "thread.pgc"
  char  l_connection [ 128 ]    ;
 /* exec sql end declare section */
-#line 87 "thread.pgc"
+#line 103 "thread.pgc"
 
 
   /* build up connection name, and connect to database */
   snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
   /* exec sql whenever sqlerror  sqlprint ; */
-#line 91 "thread.pgc"
+#line 107 "thread.pgc"
 
   { ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , l_connection, 0); 
-#line 92 "thread.pgc"
+#line 108 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 92 "thread.pgc"
+#line 108 "thread.pgc"
 
   if( sqlca.sqlcode != 0 )
     {
@@ -153,10 +169,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
       return( NULL );
     }
   { ECPGtrans(__LINE__, l_connection, "begin transaction ");
-#line 98 "thread.pgc"
+#line 114 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 98 "thread.pgc"
+#line 114 "thread.pgc"
 
 
   /* insert into test_thread table */
@@ -167,10 +183,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_int,&(l_i),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
-#line 103 "thread.pgc"
+#line 119 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 103 "thread.pgc"
+#line 119 "thread.pgc"
 
       if( sqlca.sqlcode != 0 )
 	printf("%s: ERROR: insert failed!\n", l_connection);
@@ -178,16 +194,16 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
   /* all done */
   { ECPGtrans(__LINE__, l_connection, "commit");
-#line 109 "thread.pgc"
+#line 125 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 109 "thread.pgc"
+#line 125 "thread.pgc"
 
   { ECPGdisconnect(__LINE__, l_connection);
-#line 110 "thread.pgc"
+#line 126 "thread.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 110 "thread.pgc"
+#line 126 "thread.pgc"
 
   return( NULL );
 }
diff --git a/src/interfaces/ecpg/test/expected/thread-thread_implicit.c b/src/interfaces/ecpg/test/expected/thread-thread_implicit.c
index 1fd3faa48d5..f48db90559a 100644
--- a/src/interfaces/ecpg/test/expected/thread-thread_implicit.c
+++ b/src/interfaces/ecpg/test/expected/thread-thread_implicit.c
@@ -24,7 +24,11 @@ main(void)
 	return 0;
 }
 #else
+#ifndef WIN32
 #include <pthread.h>
+#else
+#include <windows.h>
+#endif
 
 
 #line 1 "regression.h"
@@ -34,7 +38,7 @@ main(void)
 
 
 
-#line 19 "thread_implicit.pgc"
+#line 23 "thread_implicit.pgc"
 
 
 void *test_thread(void *arg);
@@ -44,15 +48,19 @@ int iterations = 20;
 
 int main(int argc, char *argv[])
 {
+#ifndef WIN32
   pthread_t *threads;
+#else
+  HANDLE *threads;
+#endif
   int n;
   /* exec sql begin declare section */
    
   
-#line 31 "thread_implicit.pgc"
+#line 39 "thread_implicit.pgc"
  int  l_rows    ;
 /* exec sql end declare section */
-#line 32 "thread_implicit.pgc"
+#line 40 "thread_implicit.pgc"
 
 
  /* Do not switch on debug output for regression tests. The threads get executed in
@@ -61,26 +69,26 @@ int main(int argc, char *argv[])
 
   /* setup test_thread table */
   { ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0); }
-#line 39 "thread_implicit.pgc"
+#line 47 "thread_implicit.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, "drop table test_thread ", ECPGt_EOIT, ECPGt_EORT);}
-#line 40 "thread_implicit.pgc"
+#line 48 "thread_implicit.pgc"
  /* DROP might fail */
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 41 "thread_implicit.pgc"
+#line 49 "thread_implicit.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, "create  table test_thread ( tstamp timestamp    not null default cast( timeofday () as timestamp   ) , thread TEXT    not null , iteration integer   not null , primary key( thread , iteration )   )    ", ECPGt_EOIT, ECPGt_EORT);}
-#line 46 "thread_implicit.pgc"
+#line 54 "thread_implicit.pgc"
 
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 47 "thread_implicit.pgc"
+#line 55 "thread_implicit.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
-#line 48 "thread_implicit.pgc"
+#line 56 "thread_implicit.pgc"
 
 
   /* create, and start, threads */
-  threads = calloc(nthreads, sizeof(pthread_t));
+  threads = calloc(nthreads, sizeof(threads[0]));
   if( threads == NULL )
     {
       fprintf(stderr, "Cannot alloc memory\n");
@@ -88,30 +96,38 @@ int main(int argc, char *argv[])
     }
   for( n = 0; n < nthreads; n++ )
     {
+#ifndef WIN32
       pthread_create(&threads[n], NULL, test_thread, (void *) (n + 1));
+#else
+      threads[n] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) test_thread, (void *) (n+1), 0, NULL);
+#endif
     }
 
   /* wait for thread completion */
+#ifndef WIN32
   for( n = 0; n < nthreads; n++ )
     {
       pthread_join(threads[n], NULL);
     }
+#else
+  WaitForMultipleObjects(nthreads, threads, TRUE, INFINITE);
+#endif
   free(threads);
 
   /* and check results */
   { ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0); }
-#line 70 "thread_implicit.pgc"
+#line 86 "thread_implicit.pgc"
 
   { ECPGdo(__LINE__, 0, 1, NULL, "select  count (*)  from test_thread   ", ECPGt_EOIT, 
 	ECPGt_int,&(l_rows),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
-#line 71 "thread_implicit.pgc"
+#line 87 "thread_implicit.pgc"
 
   { ECPGtrans(__LINE__, NULL, "commit");}
-#line 72 "thread_implicit.pgc"
+#line 88 "thread_implicit.pgc"
 
   { ECPGdisconnect(__LINE__, "CURRENT");}
-#line 73 "thread_implicit.pgc"
+#line 89 "thread_implicit.pgc"
 
   if( l_rows == (nthreads * iterations) )
     printf("Success.\n");
@@ -128,25 +144,25 @@ void *test_thread(void *arg)
     
    
   
-#line 86 "thread_implicit.pgc"
+#line 102 "thread_implicit.pgc"
  int  l_i    ;
  
-#line 87 "thread_implicit.pgc"
+#line 103 "thread_implicit.pgc"
  char  l_connection [ 128 ]    ;
 /* exec sql end declare section */
-#line 88 "thread_implicit.pgc"
+#line 104 "thread_implicit.pgc"
 
 
   /* build up connection name, and connect to database */
   snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
   /* exec sql whenever sqlerror  sqlprint ; */
-#line 92 "thread_implicit.pgc"
+#line 108 "thread_implicit.pgc"
 
   { ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , l_connection, 0); 
-#line 93 "thread_implicit.pgc"
+#line 109 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 93 "thread_implicit.pgc"
+#line 109 "thread_implicit.pgc"
 
   if( sqlca.sqlcode != 0 )
     {
@@ -154,10 +170,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
       return( NULL );
     }
   { ECPGtrans(__LINE__, NULL, "begin transaction ");
-#line 99 "thread_implicit.pgc"
+#line 115 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 99 "thread_implicit.pgc"
+#line 115 "thread_implicit.pgc"
 
 
   /* insert into test_thread table */
@@ -168,10 +184,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_int,&(l_i),(long)1,(long)1,sizeof(int), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
-#line 104 "thread_implicit.pgc"
+#line 120 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 104 "thread_implicit.pgc"
+#line 120 "thread_implicit.pgc"
 
       if( sqlca.sqlcode != 0 )
 	printf("%s: ERROR: insert failed!\n", l_connection);
@@ -179,16 +195,16 @@ if (sqlca.sqlcode < 0) sqlprint();}
 
   /* all done */
   { ECPGtrans(__LINE__, NULL, "commit");
-#line 110 "thread_implicit.pgc"
+#line 126 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 110 "thread_implicit.pgc"
+#line 126 "thread_implicit.pgc"
 
   { ECPGdisconnect(__LINE__, l_connection);
-#line 111 "thread_implicit.pgc"
+#line 127 "thread_implicit.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
-#line 111 "thread_implicit.pgc"
+#line 127 "thread_implicit.pgc"
 
   return( NULL );
 }
diff --git a/src/interfaces/ecpg/test/thread/thread.pgc b/src/interfaces/ecpg/test/thread/thread.pgc
index e7f0b4d1dca..726121d2ca2 100644
--- a/src/interfaces/ecpg/test/thread/thread.pgc
+++ b/src/interfaces/ecpg/test/thread/thread.pgc
@@ -13,7 +13,11 @@ main(void)
 	return 0;
 }
 #else
+#ifndef WIN32
 #include <pthread.h>
+#else
+#include <windows.h>
+#endif
 
 exec sql include ../regression;
 
@@ -24,7 +28,11 @@ int iterations = 20;
 
 int main(int argc, char *argv[])
 {
+#ifndef WIN32
   pthread_t *threads;
+#else
+  HANDLE *threads;
+#endif
   int n;
   EXEC SQL BEGIN DECLARE SECTION;
   int l_rows;
@@ -47,7 +55,7 @@ int main(int argc, char *argv[])
   EXEC SQL DISCONNECT;
 
   /* create, and start, threads */
-  threads = calloc(nthreads, sizeof(pthread_t));
+  threads = calloc(nthreads, sizeof(threads[0]));
   if( threads == NULL )
     {
       fprintf(stderr, "Cannot alloc memory\n");
@@ -55,14 +63,22 @@ int main(int argc, char *argv[])
     }
   for( n = 0; n < nthreads; n++ )
     {
+#ifndef WIN32
       pthread_create(&threads[n], NULL, test_thread, (void *) (n + 1));
+#else
+      threads[n] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)test_thread, (void *) (n + 1), 0, NULL);
+#endif
     }
 
   /* wait for thread completion */
+#ifndef WIN32
   for( n = 0; n < nthreads; n++ )
     {
       pthread_join(threads[n], NULL);
     }
+#else
+  WaitForMultipleObjects(nthreads, threads, TRUE, INFINITE);
+#endif
   free(threads);
 
   /* and check results */
diff --git a/src/interfaces/ecpg/test/thread/thread_implicit.pgc b/src/interfaces/ecpg/test/thread/thread_implicit.pgc
index e4033849600..010a8e52051 100644
--- a/src/interfaces/ecpg/test/thread/thread_implicit.pgc
+++ b/src/interfaces/ecpg/test/thread/thread_implicit.pgc
@@ -14,7 +14,11 @@ main(void)
 	return 0;
 }
 #else
+#ifndef WIN32
 #include <pthread.h>
+#else
+#include <windows.h>
+#endif
 
 exec sql include ../regression;
 
@@ -25,7 +29,11 @@ int iterations = 20;
 
 int main(int argc, char *argv[])
 {
+#ifndef WIN32
   pthread_t *threads;
+#else
+  HANDLE *threads;
+#endif
   int n;
   EXEC SQL BEGIN DECLARE SECTION;
   int l_rows;
@@ -48,7 +56,7 @@ int main(int argc, char *argv[])
   EXEC SQL DISCONNECT;
 
   /* create, and start, threads */
-  threads = calloc(nthreads, sizeof(pthread_t));
+  threads = calloc(nthreads, sizeof(threads[0]));
   if( threads == NULL )
     {
       fprintf(stderr, "Cannot alloc memory\n");
@@ -56,14 +64,22 @@ int main(int argc, char *argv[])
     }
   for( n = 0; n < nthreads; n++ )
     {
+#ifndef WIN32
       pthread_create(&threads[n], NULL, test_thread, (void *) (n + 1));
+#else
+      threads[n] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) test_thread, (void *) (n+1), 0, NULL);
+#endif
     }
 
   /* wait for thread completion */
+#ifndef WIN32
   for( n = 0; n < nthreads; n++ )
     {
       pthread_join(threads[n], NULL);
     }
+#else
+  WaitForMultipleObjects(nthreads, threads, TRUE, INFINITE);
+#endif
   free(threads);
 
   /* and check results */
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index 35294adca72..35412ae6feb 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -3,7 +3,7 @@ package Mkvcbuild;
 #
 # Package that generates build files for msvc build
 #
-# $PostgreSQL: pgsql/src/tools/msvc/Mkvcbuild.pm,v 1.6 2007/03/24 14:13:27 mha Exp $
+# $PostgreSQL: pgsql/src/tools/msvc/Mkvcbuild.pm,v 1.7 2007/03/29 15:30:52 mha Exp $
 #
 use Carp;
 use Win32;
@@ -131,38 +131,28 @@ sub mkvcbuild
     $pgtypes->AddReference($postgres,$libpgport);
     $pgtypes->AddIncludeDir('src\interfaces\ecpg\include');
 
-    if ($config->{pthread})
-    {
-        my $libecpg =
-          $solution->AddProject('libecpg','dll','interfaces','src\interfaces\ecpg\ecpglib');
-        $libecpg->AddDefine('FRONTEND');
-        $libecpg->AddIncludeDir('src\interfaces\ecpg\include');
-        $libecpg->AddIncludeDir('src\interfaces\libpq');
-        $libecpg->AddIncludeDir('src\port');
-        $libecpg->AddLibrary('wsock32.lib');
-        $libecpg->AddLibrary($config->{'pthread'} . '\pthreadVC2.lib');
-        $libecpg->AddReference($libpq,$pgtypes,$libpgport);
-
-        my $libecpgcompat =
-          $solution->AddProject('libecpg_compat','dll','interfaces',
-            'src\interfaces\ecpg\compatlib');
-        $libecpgcompat->AddIncludeDir('src\interfaces\ecpg\include');
-        $libecpgcompat->AddIncludeDir('src\interfaces\libpq');
-        $libecpgcompat->AddReference($pgtypes,$libecpg);
-
-        my $ecpg = $solution->AddProject('ecpg','exe','interfaces','src\interfaces\ecpg\preproc');
-        $ecpg->AddIncludeDir('src\interfaces\ecpg\include');
-        $ecpg->AddIncludeDir('src\interfaces\libpq');
-        $ecpg->AddFiles('src\interfaces\ecpg\preproc','pgc.l','preproc.y');
-        $ecpg->AddDefine('MAJOR_VERSION=4');
-        $ecpg->AddDefine('MINOR_VERSION=2');
-        $ecpg->AddDefine('PATCHLEVEL=1');
-        $ecpg->AddReference($libpgport);
-    }
-    else
-    {
-        print "Not building ecpg due to lack of pthreads.\n";
-    }
+    my $libecpg =$solution->AddProject('libecpg','dll','interfaces','src\interfaces\ecpg\ecpglib');
+    $libecpg->AddDefine('FRONTEND');
+    $libecpg->AddIncludeDir('src\interfaces\ecpg\include');
+    $libecpg->AddIncludeDir('src\interfaces\libpq');
+    $libecpg->AddIncludeDir('src\port');
+    $libecpg->AddLibrary('wsock32.lib');
+    $libecpg->AddReference($libpq,$pgtypes,$libpgport);
+
+    my $libecpgcompat =
+      $solution->AddProject('libecpg_compat','dll','interfaces','src\interfaces\ecpg\compatlib');
+    $libecpgcompat->AddIncludeDir('src\interfaces\ecpg\include');
+    $libecpgcompat->AddIncludeDir('src\interfaces\libpq');
+    $libecpgcompat->AddReference($pgtypes,$libecpg);
+
+    my $ecpg = $solution->AddProject('ecpg','exe','interfaces','src\interfaces\ecpg\preproc');
+    $ecpg->AddIncludeDir('src\interfaces\ecpg\include');
+    $ecpg->AddIncludeDir('src\interfaces\libpq');
+    $ecpg->AddFiles('src\interfaces\ecpg\preproc','pgc.l','preproc.y');
+    $ecpg->AddDefine('MAJOR_VERSION=4');
+    $ecpg->AddDefine('MINOR_VERSION=2');
+    $ecpg->AddDefine('PATCHLEVEL=1');
+    $ecpg->AddReference($libpgport);
 
     # src/bin
     my $initdb = AddSimpleFrontend('initdb', 1);
diff --git a/src/tools/msvc/Project.pm b/src/tools/msvc/Project.pm
index 0623a4f9985..f35580bface 100644
--- a/src/tools/msvc/Project.pm
+++ b/src/tools/msvc/Project.pm
@@ -1,8 +1,9 @@
 package Project;
+
 #
 # Package that encapsulates a Visual C++ project file generation
 #
-# $PostgreSQL: pgsql/src/tools/msvc/Project.pm,v 1.10 2007/03/17 14:01:01 mha Exp $
+# $PostgreSQL: pgsql/src/tools/msvc/Project.pm,v 1.11 2007/03/29 15:30:52 mha Exp $
 #
 use Carp;
 use strict;
@@ -462,13 +463,11 @@ sub WriteConfiguration
     }
     $libs =~ s/ $//;
     $libs =~ s/__CFGNAME__/$cfgname/g;
-    my $pth = $self->{solution}->{options}->{pthread};
-    $pth = '' unless $pth;
     print $f <<EOF;
   <Configuration Name="$cfgname|Win32" OutputDirectory=".\\$cfgname\\$self->{name}" IntermediateDirectory=".\\$cfgname\\$self->{name}"
 	ConfigurationType="$cfgtype" UseOfMFC="0" ATLMinimizesCRunTimeLibraryUsage="FALSE" CharacterSet="2" WholeProgramOptimization="$p->{wholeopt}">
 	<Tool Name="VCCLCompilerTool" Optimization="$p->{opt}"
-		AdditionalIncludeDirectories="src/include;src/include/port/win32;src/include/port/win32_msvc;$pth;$self->{includes}"
+		AdditionalIncludeDirectories="src/include;src/include/port/win32;src/include/port/win32_msvc;$self->{includes}"
 		PreprocessorDefinitions="WIN32;_WINDOWS;__WINDOWS__;__WIN32__;EXEC_BACKEND;WIN32_STACK_RLIMIT=4194304;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE$self->{defines}$p->{defs}"
 		StringPooling="$p->{strpool}"
 		RuntimeLibrary="$p->{runtime}" DisableSpecificWarnings="$self->{disablewarnings}"
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index e665b49866e..66340c9e3fd 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -1,8 +1,9 @@
 package Solution;
+
 #
 # Package that encapsulates a Visual C++ solution file generation
-# 
-# $PostgreSQL: pgsql/src/tools/msvc/Solution.pm,v 1.19 2007/03/24 22:16:49 mha Exp $
+#
+# $PostgreSQL: pgsql/src/tools/msvc/Solution.pm,v 1.20 2007/03/29 15:30:52 mha Exp $
 #
 use Carp;
 use strict;
@@ -104,7 +105,7 @@ s{PG_VERSION_STR "[^"]+"}{__STRINGIFY(x) #x\n#define __STRINGIFY2(z) __STRINGIFY
         }
         print O "#define LOCALEDIR \"/share/locale\"\n" if ($self->{options}->{nls});
         print O "/* defines added by config steps */\n";
-	print O "#ifndef IGNORE_CONFIGURED_SETTINGS\n";
+        print O "#ifndef IGNORE_CONFIGURED_SETTINGS\n";
         print O "#define USE_ASSERT_CHECKING 1\n" if ($self->{options}->{asserts});
         print O "#define USE_INTEGER_DATETIMES 1\n" if ($self->{options}->{integer_datetimes});
         print O "#define USE_LDAP 1\n" if ($self->{options}->{ldap});
@@ -124,7 +125,7 @@ s{PG_VERSION_STR "[^"]+"}{__STRINGIFY(x) #x\n#define __STRINGIFY2(z) __STRINGIFY
             print O "#define HAVE_KRB5_TICKET_ENC_PART2 1\n";
             print O "#define PG_KRB_SRVNAM \"postgres\"\n";
         }
-	print O "#endif /* IGNORE_CONFIGURED_SETTINGS */\n";
+        print O "#endif /* IGNORE_CONFIGURED_SETTINGS */\n";
         close(O);
         close(I);
     }
@@ -239,6 +240,7 @@ s{PG_VERSION_STR "[^"]+"}{__STRINGIFY(x) #x\n#define __STRINGIFY2(z) __STRINGIFY
         print O <<EOF;
 #if (_MSC_VER > 1200)
 #define HAVE_LONG_LONG_INT_64
+#define ENABLE_THREAD_SAFETY 1
 #endif
 EOF
         close(O);
diff --git a/src/tools/msvc/config.pl b/src/tools/msvc/config.pl
index 40c0f85dcf2..755f27ec970 100644
--- a/src/tools/msvc/config.pl
+++ b/src/tools/msvc/config.pl
@@ -12,7 +12,6 @@ our $config = {
     krb5=>'c:\prog\pgsql\depend\krb5', # --with-krb5=<path>
     ldap=>1,			# --with-ldap
     openssl=>'c:\openssl', # --with-ssl=<path>
-    pthread=>'c:\prog\pgsql\depend\pthread',
     xml=>'c:\prog\pgsql\depend\libxml2',
     xslt=>'c:\prog\pgsql\depend\libxslt',
     iconv=>'c:\prog\pgsql\depend\iconv',
-- 
GitLab