aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/ecpg/ecpglib
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces/ecpg/ecpglib')
-rw-r--r--src/interfaces/ecpg/ecpglib/connect.c28
-rw-r--r--src/interfaces/ecpg/ecpglib/extern.h3
-rw-r--r--src/interfaces/ecpg/ecpglib/memory.c85
-rw-r--r--src/interfaces/ecpg/ecpglib/misc.c76
-rw-r--r--src/interfaces/ecpg/ecpglib/prepare.c20
5 files changed, 119 insertions, 93 deletions
diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c
index 40f5d7ead34..8d4146cfae3 100644
--- a/src/interfaces/ecpg/ecpglib/connect.c
+++ b/src/interfaces/ecpg/ecpglib/connect.c
@@ -1,15 +1,9 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.43 2007/09/26 10:57:00 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.44 2007/09/30 11:38:48 meskes Exp $ */
#define POSTGRES_ECPG_INTERNAL
#include "postgres_fe.h"
-#ifdef ENABLE_THREAD_SAFETY
-#ifndef WIN32
-#include <pthread.h>
-#else
#include "ecpg-pthread-win32.h"
-#endif
-#endif
#include "ecpgtype.h"
#include "ecpglib.h"
#include "ecpgerrno.h"
@@ -17,20 +11,17 @@
#include "sqlca.h"
#ifdef ENABLE_THREAD_SAFETY
+NON_EXEC_STATIC pthread_mutex_t connections_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_key_t actual_connection_key;
#ifndef WIN32
-static pthread_mutex_t connections_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_key_t actual_connection_key;
-static pthread_once_t actual_connection_key_once = PTHREAD_ONCE_INIT;
-#else
-static HANDLE connections_mutex = INVALID_HANDLE_VALUE;
-static DWORD actual_connection_key;
-#endif /* 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
-static void
+NON_EXEC_STATIC void
ecpg_actual_connection_init(void)
{
pthread_key_create(&actual_connection_key, NULL);
@@ -39,13 +30,7 @@ ecpg_actual_connection_init(void)
void
ecpg_pthreads_init(void)
{
-#ifndef WIN32
pthread_once(&actual_connection_key_once, ecpg_actual_connection_init);
-#else
- static long has_run = 0;
- if (InterlockedCompareExchange(&has_run, 1, 0) == 0)
- ecpg_actual_connection_init();
-#endif
}
#endif
@@ -134,6 +119,7 @@ ecpg_finish(struct connection * act)
struct ECPGtype_information_cache *cache,
*ptr;
+ ECPGdeallocate_all_conn(0, ECPG_COMPAT_PGSQL, act);
PQfinish(act->connection);
/*
diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h
index f69730740be..f7e91d31270 100644
--- a/src/interfaces/ecpg/ecpglib/extern.h
+++ b/src/interfaces/ecpg/ecpglib/extern.h
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/extern.h,v 1.27 2007/09/26 10:57:00 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/extern.h,v 1.28 2007/09/30 11:38:48 meskes Exp $ */
#ifndef _ECPG_LIB_EXTERN_H
#define _ECPG_LIB_EXTERN_H
@@ -146,6 +146,7 @@ bool ECPGcheck_PQresult(PGresult *, int, PGconn *, enum COMPAT_MODE);
void ECPGraise(int line, int code, const char *sqlstate, const char *str);
void ECPGraise_backend(int line, PGresult *result, PGconn *conn, int compat);
char *ECPGprepared(const char *, struct connection *, int);
+bool ECPGdeallocate_all_conn(int lineno, enum COMPAT_MODE c, struct connection *conn);
/* SQLSTATE values generated or processed by ecpglib (intentionally
* not exported -- users should refer to the codes directly) */
diff --git a/src/interfaces/ecpg/ecpglib/memory.c b/src/interfaces/ecpg/ecpglib/memory.c
index 3ee89a189a1..0b3eb47d4e1 100644
--- a/src/interfaces/ecpg/ecpglib/memory.c
+++ b/src/interfaces/ecpg/ecpglib/memory.c
@@ -1,8 +1,9 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/memory.c,v 1.8 2006/11/08 10:46:47 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/memory.c,v 1.9 2007/09/30 11:38:48 meskes Exp $ */
#define POSTGRES_ECPG_INTERNAL
#include "postgres_fe.h"
+#include "ecpg-pthread-win32.h"
#include "ecpgtype.h"
#include "ecpglib.h"
#include "ecpgerrno.h"
@@ -25,7 +26,6 @@ ECPGalloc(long size, int lineno)
return NULL;
}
- memset(new, '\0', size);
return (new);
}
@@ -62,11 +62,48 @@ ECPGstrdup(const char *string, int lineno)
}
/* keep a list of memory we allocated for the user */
-static struct auto_mem
+struct auto_mem
{
void *pointer;
struct auto_mem *next;
-} *auto_allocs = NULL;
+};
+
+#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
+auto_mem_key_init(void)
+{
+ pthread_key_create(&auto_mem_key, auto_mem_destructor);
+}
+
+static struct auto_mem *
+get_auto_allocs(void)
+{
+ pthread_once(&auto_mem_once, auto_mem_key_init);
+ return (struct auto_mem *) pthread_getspecific(auto_mem_key);
+}
+
+static void
+set_auto_allocs(struct auto_mem *am)
+{
+ pthread_setspecific(auto_mem_key, am);
+}
+
+#else
+static struct auto_mem *auto_allocs = NULL;
+#define get_auto_allocs() (auto_allocs)
+#define set_auto_allocs(am) do { auto_allocs = (am); } while(0)
+#endif
void
ECPGadd_mem(void *ptr, int lineno)
@@ -74,41 +111,43 @@ ECPGadd_mem(void *ptr, int lineno)
struct auto_mem *am = (struct auto_mem *) ECPGalloc(sizeof(struct auto_mem), lineno);
am->pointer = ptr;
- am->next = auto_allocs;
- auto_allocs = am;
+ am->next = get_auto_allocs();
+ set_auto_allocs(am);
}
void
ECPGfree_auto_mem(void)
{
- struct auto_mem *am;
+ struct auto_mem *am = get_auto_allocs();
/* free all memory we have allocated for the user */
- for (am = auto_allocs; am;)
+ if (am)
{
- struct auto_mem *act = am;
-
- am = am->next;
- ECPGfree(act->pointer);
- ECPGfree(act);
+ do
+ {
+ struct auto_mem *act = am;
+ am = am->next;
+ ECPGfree(act->pointer);
+ ECPGfree(act);
+ } while(am);
+ set_auto_allocs(NULL);
}
-
- auto_allocs = NULL;
}
void
ECPGclear_auto_mem(void)
{
- struct auto_mem *am;
+ struct auto_mem *am = get_auto_allocs();
/* only free our own structure */
- for (am = auto_allocs; am;)
+ if (am)
{
- struct auto_mem *act = am;
-
- am = am->next;
- ECPGfree(act);
+ do
+ {
+ struct auto_mem *act = am;
+ am = am->next;
+ ECPGfree(act);
+ } while(am);
+ set_auto_allocs(NULL);
}
-
- auto_allocs = NULL;
}
diff --git a/src/interfaces/ecpg/ecpglib/misc.c b/src/interfaces/ecpg/ecpglib/misc.c
index 1da37ec5f77..4dfa8cab542 100644
--- a/src/interfaces/ecpg/ecpglib/misc.c
+++ b/src/interfaces/ecpg/ecpglib/misc.c
@@ -1,17 +1,11 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/misc.c,v 1.36 2007/08/14 10:01:52 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/misc.c,v 1.37 2007/09/30 11:38:48 meskes Exp $ */
#define POSTGRES_ECPG_INTERNAL
#include "postgres_fe.h"
#include <limits.h>
#include <unistd.h>
-#ifdef ENABLE_THREAD_SAFETY
-#ifndef WIN32
-#include <pthread.h>
-#else
#include "ecpg-pthread-win32.h"
-#endif
-#endif
#include "ecpgtype.h"
#include "ecpglib.h"
#include "ecpgerrno.h"
@@ -62,11 +56,9 @@ static struct sqlca_t sqlca_init =
};
#ifdef ENABLE_THREAD_SAFETY
-#ifndef WIN32
static pthread_key_t sqlca_key;
+#ifndef WIN32
static pthread_once_t sqlca_key_once = PTHREAD_ONCE_INIT;
-#else
-static DWORD sqlca_key;
#endif
#else
static struct sqlca_t sqlca =
@@ -98,13 +90,8 @@ static struct sqlca_t sqlca =
#endif
#ifdef ENABLE_THREAD_SAFETY
-#ifndef WIN32
-static pthread_mutex_t debug_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t debug_init_mutex = PTHREAD_MUTEX_INITIALIZER;
-#else
-static HANDLE debug_mutex = INVALID_HANDLE_VALUE;
-static HANDLE debug_init_mutex = INVALID_HANDLE_VALUE;
-#endif /* WIN32 */
+NON_EXEC_STATIC pthread_mutex_t debug_mutex = PTHREAD_MUTEX_INITIALIZER;
+NON_EXEC_STATIC pthread_mutex_t debug_init_mutex = PTHREAD_MUTEX_INITIALIZER;
#endif
static int simple_debug = 0;
static FILE *debugstream = NULL;
@@ -135,11 +122,10 @@ ECPGinit(const struct connection * con, const char *connection_name, const int l
static void
ecpg_sqlca_key_destructor(void *arg)
{
- if (arg != NULL)
- free(arg); /* sqlca structure allocated in ECPGget_sqlca */
+ free(arg); /* sqlca structure allocated in ECPGget_sqlca */
}
-static void
+NON_EXEC_STATIC void
ecpg_sqlca_key_init(void)
{
pthread_key_create(&sqlca_key, ecpg_sqlca_key_destructor);
@@ -151,13 +137,8 @@ ECPGget_sqlca(void)
{
#ifdef ENABLE_THREAD_SAFETY
struct sqlca_t *sqlca;
-#ifdef WIN32
- static long has_run = 0;
- if (InterlockedCompareExchange(&has_run, 1, 0) == 0)
- ecpg_sqlca_key_init();
-#else
+
pthread_once(&sqlca_key_once, ecpg_sqlca_key_init);
-#endif
sqlca = pthread_getspecific(sqlca_key);
if (sqlca == NULL)
@@ -263,22 +244,13 @@ ECPGlog(const char *format,...)
va_list ap;
struct sqlca_t *sqlca = ECPGget_sqlca();
-#ifdef ENABLE_THREAD_SAFETY
- pthread_mutex_lock(&debug_mutex);
-#endif
-
if (simple_debug)
{
int bufsize = strlen(format) + 100;
char *f = (char *) malloc(bufsize);
if (f == NULL)
- {
-#ifdef ENABLE_THREAD_SAFETY
- pthread_mutex_unlock(&debug_mutex);
-#endif
return;
- }
/*
* regression tests set this environment variable to get the same
@@ -289,6 +261,10 @@ ECPGlog(const char *format,...)
else
snprintf(f, bufsize, "[%d]: %s", (int) getpid(), format);
+#ifdef ENABLE_THREAD_SAFETY
+ pthread_mutex_lock(&debug_mutex);
+#endif
+
va_start(ap, format);
vfprintf(debugstream, f, ap);
va_end(ap);
@@ -300,12 +276,12 @@ ECPGlog(const char *format,...)
fflush(debugstream);
- ECPGfree(f);
- }
-
#ifdef ENABLE_THREAD_SAFETY
- pthread_mutex_unlock(&debug_mutex);
+ pthread_mutex_unlock(&debug_mutex);
#endif
+
+ free(f);
+ }
}
void
@@ -437,3 +413,25 @@ ECPGis_noind_null(enum ECPGttype type, void *ptr)
return false;
}
+
+#ifdef WIN32
+
+/*
+ * Initialize mutexes and call init-once functions on loading.
+ */
+
+BOOL WINAPI
+DllMain(HANDLE module, DWORD reason, LPVOID reserved)
+{
+ if (reason == DLL_PROCESS_ATTACH)
+ {
+ 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();
+ }
+ return TRUE;
+}
+#endif
diff --git a/src/interfaces/ecpg/ecpglib/prepare.c b/src/interfaces/ecpg/ecpglib/prepare.c
index 6d884bfb0ae..1afa63c9339 100644
--- a/src/interfaces/ecpg/ecpglib/prepare.c
+++ b/src/interfaces/ecpg/ecpglib/prepare.c
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/prepare.c,v 1.20 2007/09/26 10:57:00 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/prepare.c,v 1.21 2007/09/30 11:38:48 meskes Exp $ */
#define POSTGRES_ECPG_INTERNAL
#include "postgres_fe.h"
@@ -31,8 +31,8 @@ typedef struct
} stmtCacheEntry;
static int nextStmtID = 1;
-static int stmtCacheNBuckets = 2039; /* # buckets - a prime # */
-static int stmtCacheEntPerBucket = 8; /* # entries/bucket */
+const static int stmtCacheNBuckets = 2039; /* # buckets - a prime # */
+const static int stmtCacheEntPerBucket = 8; /* # entries/bucket */
static stmtCacheEntry stmtCacheEntries[16384] = {{0,{0},0,0,0}};
static struct prepared_statement *find_prepared_statement(const char *name,
@@ -263,22 +263,24 @@ ECPGdeallocate(int lineno, int c, const char *connection_name, const char *name)
}
bool
-ECPGdeallocate_all(int lineno, int compat, const char *connection_name)
+ECPGdeallocate_all_conn(int lineno, enum COMPAT_MODE c, struct connection *con)
{
- struct connection *con;
-
- con = ECPGget_connection(connection_name);
-
/* deallocate all prepared statements */
while (con->prep_stmts)
{
- if (!deallocate_one(lineno, compat, con, NULL, con->prep_stmts))
+ if (!deallocate_one(lineno, c, con, NULL, con->prep_stmts))
return false;
}
return true;
}
+bool
+ECPGdeallocate_all(int lineno, int compat, const char *connection_name)
+{
+ return ECPGdeallocate_all_conn(lineno, compat, ECPGget_connection(connection_name));
+}
+
char *
ECPGprepared(const char *name, struct connection *con, int lineno)
{