diff options
Diffstat (limited to 'src/interfaces/ecpg/ecpglib')
-rw-r--r-- | src/interfaces/ecpg/ecpglib/connect.c | 28 | ||||
-rw-r--r-- | src/interfaces/ecpg/ecpglib/extern.h | 3 | ||||
-rw-r--r-- | src/interfaces/ecpg/ecpglib/memory.c | 85 | ||||
-rw-r--r-- | src/interfaces/ecpg/ecpglib/misc.c | 76 | ||||
-rw-r--r-- | src/interfaces/ecpg/ecpglib/prepare.c | 20 |
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) { |