- ITAGAKI Takahiro added thread-safe
descriptor handling
+
+Wed, 03 Oct 2007 10:48:39 +0200
+
+ - Hopefully fixed some stuff that causes Windows builds to fail.
- Set ecpg library version to 6.0.
- Set ecpg version to 4.4.
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.45 2007/10/02 09:49:59 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.46 2007/10/03 08:55:22 meskes Exp $ */
#define POSTGRES_ECPG_INTERNAL
#include "postgres_fe.h"
#include "sqlca.h"
#ifdef ENABLE_THREAD_SAFETY
-NON_EXEC_STATIC pthread_mutex_t connections_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t connections_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_key_t actual_connection_key;
-#ifndef WIN32
static pthread_once_t actual_connection_key_once = PTHREAD_ONCE_INIT;
#endif
-#endif
static struct connection *actual_connection = NULL;
static struct connection *all_connections = NULL;
#ifdef ENABLE_THREAD_SAFETY
-NON_EXEC_STATIC void
+static void
ecpg_actual_connection_init(void)
{
pthread_key_create(&actual_connection_key, NULL);
this->cache_head = NULL;
this->prep_stmts = NULL;
- this->descriptors = NULL;
if (all_connections == NULL)
this->next = NULL;
/* dynamic SQL support routines
*
- * $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/descriptor.c,v 1.24 2007/10/02 09:49:59 meskes Exp $
+ * $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/descriptor.c,v 1.25 2007/10/03 08:55:22 meskes Exp $
*/
#define POSTGRES_ECPG_INTERNAL
/* We manage descriptors separately for each thread. */
#ifdef ENABLE_THREAD_SAFETY
static pthread_key_t descriptor_key;
-#ifndef WIN32
static pthread_once_t descriptor_once = PTHREAD_ONCE_INIT;
-#endif
static void
descriptor_destructor(void *arg)
descriptor_deallocate_all(arg);
}
-NON_EXEC_STATIC void
+static void
descriptor_key_init(void)
{
pthread_key_create(&descriptor_key, descriptor_destructor);
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/extern.h,v 1.29 2007/10/02 09:49:59 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/extern.h,v 1.30 2007/10/03 08:55:22 meskes Exp $ */
#ifndef _ECPG_LIB_EXTERN_H
#define _ECPG_LIB_EXTERN_H
#ifdef ENABLE_THREAD_SAFETY
void ecpg_pthreads_init(void);
-#else
-#define ecpg_pthreads_init() ((void)0)
#endif
struct connection *ECPGget_connection(const char *);
char *ECPGalloc(long, int);
int autocommit;
struct ECPGtype_information_cache *cache_head;
struct prepared_statement *prep_stmts;
- struct descriptor *descriptors;
struct connection *next;
};
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/memory.c,v 1.9 2007/09/30 11:38:48 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/memory.c,v 1.10 2007/10/03 08:55:22 meskes Exp $ */
#define POSTGRES_ECPG_INTERNAL
#include "postgres_fe.h"
#ifdef ENABLE_THREAD_SAFETY
static pthread_key_t auto_mem_key;
-#ifndef WIN32
static pthread_once_t auto_mem_once = PTHREAD_ONCE_INIT;
-#endif
static void
auto_mem_destructor(void *arg)
ECPGfree_auto_mem();
}
-NON_EXEC_STATIC void
+static void
auto_mem_key_init(void)
{
pthread_key_create(&auto_mem_key, auto_mem_destructor);
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/misc.c,v 1.38 2007/10/02 09:49:59 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/misc.c,v 1.39 2007/10/03 08:55:22 meskes Exp $ */
#define POSTGRES_ECPG_INTERNAL
#include "postgres_fe.h"
#ifdef ENABLE_THREAD_SAFETY
static pthread_key_t sqlca_key;
-#ifndef WIN32
static pthread_once_t sqlca_key_once = PTHREAD_ONCE_INIT;
-#endif
#else
static struct sqlca_t sqlca =
{
#endif
#ifdef ENABLE_THREAD_SAFETY
-NON_EXEC_STATIC pthread_mutex_t debug_mutex = PTHREAD_MUTEX_INITIALIZER;
-NON_EXEC_STATIC pthread_mutex_t debug_init_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t debug_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t debug_init_mutex = PTHREAD_MUTEX_INITIALIZER;
#endif
static int simple_debug = 0;
static FILE *debugstream = NULL;
free(arg); /* sqlca structure allocated in ECPGget_sqlca */
}
-NON_EXEC_STATIC void
+static void
ecpg_sqlca_key_init(void)
{
pthread_key_create(&sqlca_key, ecpg_sqlca_key_destructor);
}
#ifdef WIN32
+#ifdef ENABLE_THREAD_SAFETY
+
+void
+win32_pthread_mutex(volatile pthread_mutex_t *mutex)
+{
+ if (mutex->handle == NULL)
+ {
+ while (InterlockedExchange((LONG *)&mutex->initlock, 1) == 1)
+ Sleep(0);
+ if (mutex->handle == NULL)
+ mutex->handle = CreateMutex(NULL, FALSE, NULL);
+ InterlockedExchange((LONG *)&mutex->initlock, 0);
+ }
+}
-/*
- * Initialize mutexes and call init-once functions on loading.
- */
+static pthread_mutex_t win32_pthread_once_lock = PTHREAD_MUTEX_INITIALIZER;
-BOOL WINAPI
-DllMain(HANDLE module, DWORD reason, LPVOID reserved)
+void
+win32_pthread_once(volatile pthread_once_t *once, void (*fn)(void))
{
- if (reason == DLL_PROCESS_ATTACH)
+ if (!*once)
{
- connections_mutex = CreateMutex(NULL, FALSE, NULL);
- debug_mutex = CreateMutex(NULL, FALSE, NULL);
- debug_init_mutex = CreateMutex(NULL, FALSE, NULL);
- auto_mem_key_init();
- ecpg_actual_connection_init();
- ecpg_sqlca_key_init();
- descriptor_key_init();
+ pthread_mutex_lock(&win32_pthread_once_lock);
+ if (!*once)
+ {
+ *once = true;
+ fn();
+ }
+ pthread_mutex_unlock(&win32_pthread_once_lock);
}
- return TRUE;
}
-#endif
+
+#endif /* ENABLE_THREAD_SAFETY */
+#endif /* WIN32 */
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/include/ecpg-pthread-win32.h,v 1.3 2007/10/02 09:49:59 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/include/ecpg-pthread-win32.h,v 1.4 2007/10/03 08:55:23 meskes Exp $ */
/*
* pthread mapping macros for win32 native thread implementation
*/
#ifndef WIN32
-#define NON_EXEC_STATIC static
#else
-#define NON_EXEC_STATIC
+typedef struct pthread_mutex_t
+{
+ HANDLE handle;
+ LONG initlock;
+} pthread_mutex_t;
-typedef HANDLE pthread_mutex_t;
typedef DWORD pthread_key_t;
+typedef bool pthread_once_t;
-#define PTHREAD_MUTEX_INITIALIZER INVALID_HANDLE_VALUE
+#define PTHREAD_MUTEX_INITIALIZER { NULL, 0 }
+#define PTHREAD_ONCE_INIT false
+
+void win32_pthread_mutex(volatile pthread_mutex_t *mutex);
+void win32_pthread_once(volatile pthread_once_t *once, void (*fn)(void));
#define pthread_mutex_lock(mutex) \
- WaitForSingleObject(*(mutex), INFINITE);
+ do { \
+ if ((mutex)->handle == NULL) \
+ win32_pthread_mutex((mutex)); \
+ WaitForSingleObject((mutex)->handle, INFINITE); \
+ } while(0)
#define pthread_mutex_unlock(mutex) \
- ReleaseMutex(*(mutex))
+ ReleaseMutex((mutex)->handle)
#define pthread_getspecific(key) \
TlsGetValue((key))
#define pthread_key_create(key, destructor) \
do { *(key) = TlsAlloc(); ((void)(destructor)); } while(0)
-/* init-once functions are always called when libecpg is loaded */
-#define pthread_once(key, fn) \
- ((void)0)
-
-extern pthread_mutex_t connections_mutex;
-extern pthread_mutex_t debug_mutex;
-extern pthread_mutex_t debug_init_mutex;
-extern void auto_mem_key_init(void);
-extern void ecpg_actual_connection_init(void);
-extern void ecpg_sqlca_key_init(void);
-extern void descriptor_key_init(void);
-extern BOOL WINAPI DllMain(HANDLE module, DWORD reason, LPVOID reserved);
+#define pthread_once(once, fn) \
+ do { \
+ if (!*(once)) \
+ win32_pthread_once((once), (fn)); \
+ } while(0)
#endif /* WIN32 */
#line 17 "descriptor.pgc"
-#ifdef WIN32
+#if defined(ENABLE_THREAD_SAFETY) && defined(WIN32)
static unsigned STDCALL fn(void* arg)
#else
static void* fn(void* arg)
EXEC SQL whenever sqlerror sqlprint;
EXEC SQL whenever not found sqlprint;
-#ifdef WIN32
+#if defined(ENABLE_THREAD_SAFETY) && defined(WIN32)
static unsigned STDCALL fn(void* arg)
#else
static void* fn(void* arg)