Bruce Momjian wrote:



Agreed.  My pthread book says pthread_mutex_init() should be called only
once, and we have to guarantee that.  If the Windows implentation allows
it to be called multiple times, just create a function to be called only
by Win32 that does that and leave the Unix safe.



Ok, so here's the win32 workaround with the unix stuff left untouched.
There's no memory interlocking api in win32 that wouldn't need some initializing api call itself, so we'd have to go for assembly level test-and-set code or introduce a mandatory global libpq initializing api. Considering the probably quite low usage of kerberos/ssl together with threads under win32, and the very low probability of two threads/processors (!) trying to initiate a connection at the same time, it doesn't seem to be worth the compiler hassle with assembly inline.


Regards,
Andreas


Index: interfaces/libpq/fe-connect.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/libpq/fe-connect.c,v
retrieving revision 1.274
diff -u -r1.274 fe-connect.c
--- interfaces/libpq/fe-connect.c       10 Jun 2004 22:26:24 -0000      1.274
+++ interfaces/libpq/fe-connect.c       11 Jun 2004 17:33:34 -0000
@@ -882,11 +882,13 @@
        const char *node = NULL;
        int                     ret;
 #ifdef ENABLE_THREAD_SAFETY
+#ifndef WIN32
        static pthread_once_t check_sigpipe_once = PTHREAD_ONCE_INIT;
 
        /* Check only on first connection request */
        pthread_once(&check_sigpipe_once, check_sigpipe_handler);
 #endif
+#endif
 
        if (!conn)
                return 0;
@@ -3183,11 +3185,22 @@
 }
 
 static pgthreadlock_t default_threadlock;
+
 static void
 default_threadlock(int acquire)
 {
 #ifdef ENABLE_THREAD_SAFETY
+#ifndef WIN32
        static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
+#else
+       static pthread_mutex_t singlethread_lock;
+        static int mutex_initialized = 0;
+        if (!mutex_initialized)
+        {
+                mutex_initialized = 1;
+                pthread_mutex_init(&singlethread_lock, NULL);
+        }
+#endif
        if (acquire)
                pthread_mutex_lock(&singlethread_lock);
        else
Index: interfaces/libpq/fe-secure.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/libpq/fe-secure.c,v
retrieving revision 1.41
diff -u -r1.41 fe-secure.c
--- interfaces/libpq/fe-secure.c        3 Jun 2004 00:13:19 -0000       1.41
+++ interfaces/libpq/fe-secure.c        11 Jun 2004 17:33:36 -0000
@@ -864,8 +864,17 @@
 init_ssl_system(PGconn *conn)
 {
 #ifdef ENABLE_THREAD_SAFETY
-static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
-
+#ifndef WIN32
+        static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
+    #else
+        static pthread_mutex_t init_mutex;
+        static int mutex_initialized = 0;
+        if (!mutex_initialized)
+        {
+                mutex_initialized = 1;
+                pthread_mutex_init(&init_mutex, NULL);
+        }
+#endif
        pthread_mutex_lock(&init_mutex);
        
        if (pq_initssllib && pq_lockarray == NULL) {
@@ -1171,6 +1180,7 @@
 
 
 #ifdef ENABLE_THREAD_SAFETY
+#ifndef WIN32
 /*
  *     Check SIGPIPE handler and perhaps install our own.
  */
@@ -1210,6 +1220,7 @@
        if (!PQinSend())
                exit(128 + SIGPIPE);    /* typical return value for SIG_DFL */
 }
+#endif
 #endif
  
 /*
Index: interfaces/libpq/win32.mak
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/libpq/win32.mak,v
retrieving revision 1.24
diff -u -r1.24 win32.mak
--- interfaces/libpq/win32.mak  4 Jun 2004 13:30:04 -0000       1.24
+++ interfaces/libpq/win32.mak  11 Jun 2004 17:33:37 -0000
@@ -74,21 +74,25 @@
        [EMAIL PROTECTED] "$(OUTDIR)\$(OUTFILENAME)dll.lib"
        [EMAIL PROTECTED] "$(INTDIR)\wchar.obj"
        [EMAIL PROTECTED] "$(INTDIR)\encnames.obj"
+       [EMAIL PROTECTED] "$(INTDIR)\pthread-win32.obj"
 
 
 
-config: ..\..\include\pg_config.h pg_config_paths.h
+config: ..\..\include\pg_config.h pthread.h pg_config_paths.h
 
 ..\..\include\pg_config.h: ..\..\include\pg_config.h.win32
        copy ..\..\include\pg_config.h.win32 ..\..\include\pg_config.h
 
+pthread.h: pthread.h.win32
+       copy pthread.h.win32 pthread.h
+
 pg_config_paths.h: win32.mak
        echo #define SYSCONFDIR "" >pg_config_paths.h
 
 "$(OUTDIR)" :
     if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
 
-CPP_PROJ=/nologo /W3 /GX $(OPT) /I "..\..\include" /D "FRONTEND" $(DEBUGDEF) /D\
+CPP_PROJ=/nologo /W3 /GX $(OPT) /I "..\..\include" /I. /D "FRONTEND" $(DEBUGDEF) /D\
  "WIN32" /D "_WINDOWS" /Fp"$(INTDIR)\libpq.pch" /YX\
  /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c  /D "HAVE_VSNPRINTF" /D "HAVE_STRDUP"
 
@@ -127,7 +131,8 @@
        "$(INTDIR)\fe-secure.obj" \
        "$(INTDIR)\pqexpbuffer.obj" \
        "$(INTDIR)\wchar.obj" \
-       "$(INTDIR)\encnames.obj"
+       "$(INTDIR)\encnames.obj" \
+       "$(INTDIR)\pthread-win32.obj"
 
 
 RSC_PROJ=/l 0x409 /fo"$(INTDIR)\libpq.res"
/*-------------------------------------------------------------------------
*
* pthread-win32.c
*    partial pthread implementation for win32
*
* Copyright (c) 2004, PostgreSQL Global Development Group
* IDENTIFICATION
*   $PostgreSQL: $ 
*
*-------------------------------------------------------------------------
*/


#include "windows.h"
#include "pthread.h"

HANDLE pthread_self()
{
   return GetCurrentThread();
}

void pthread_setspecific(pthread_key_t key, void *val)
{
}

void *pthread_getspecific(pthread_key_t key)
{
    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);
}
#ifndef __PTHREAD_H
#define __PTHREAD_H

typedef ULONG pthread_key_t;
typedef HANDLE pthread_mutex_t;
typedef int pthread_once_t;

HANDLE pthread_self();

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
---------------------------(end of broadcast)---------------------------
TIP 2: you can get off all lists at once with the unregister command
    (send "unregister YourEmailAddressHere" to [EMAIL PROTECTED])

Reply via email to