Skip to content

Commit 60e83ce

Browse files
author
Michael Meskes
committed
Applied another patch by ITAGAKI Takahiro <itagaki.takahiro@oss.ntt.co.jp>
to get memory allocation thread-safe. He also did some cleaning up.
1 parent ae57efe commit 60e83ce

20 files changed

+431
-112
lines changed

src/interfaces/ecpg/ChangeLog

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2242,5 +2242,10 @@ Mi 26. Sep 12:45:51 CEST 2007
22422242

22432243
- Applied patch by ITAGAKI Takahiro <itagaki.takahiro@oss.ntt.co.jp>
22442244
to get prepare thread-safe.
2245+
2246+
Sun, 30 Sep 2007 13:37:31 +0200
2247+
2248+
- Applied another patch by ITAGAKI Takahiro <itagaki.takahiro@oss.ntt.co.jp>
2249+
to get memory allocation thread-safe. He also did some cleaning up.
22452250
- Set ecpg library version to 6.0.
22462251
- Set ecpg version to 4.4.

src/interfaces/ecpg/ecpglib/connect.c

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,27 @@
1-
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.43 2007/09/26 10:57:00 meskes Exp $ */
1+
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.44 2007/09/30 11:38:48 meskes Exp $ */
22

33
#define POSTGRES_ECPG_INTERNAL
44
#include "postgres_fe.h"
55

6-
#ifdef ENABLE_THREAD_SAFETY
7-
#ifndef WIN32
8-
#include <pthread.h>
9-
#else
106
#include "ecpg-pthread-win32.h"
11-
#endif
12-
#endif
137
#include "ecpgtype.h"
148
#include "ecpglib.h"
159
#include "ecpgerrno.h"
1610
#include "extern.h"
1711
#include "sqlca.h"
1812

1913
#ifdef ENABLE_THREAD_SAFETY
14+
NON_EXEC_STATIC pthread_mutex_t connections_mutex = PTHREAD_MUTEX_INITIALIZER;
15+
static pthread_key_t actual_connection_key;
2016
#ifndef WIN32
21-
static pthread_mutex_t connections_mutex = PTHREAD_MUTEX_INITIALIZER;
22-
static pthread_key_t actual_connection_key;
23-
static pthread_once_t actual_connection_key_once = PTHREAD_ONCE_INIT;
24-
#else
25-
static HANDLE connections_mutex = INVALID_HANDLE_VALUE;
26-
static DWORD actual_connection_key;
27-
#endif /* WIN32 */
17+
static pthread_once_t actual_connection_key_once = PTHREAD_ONCE_INIT;
18+
#endif
2819
#endif
2920
static struct connection *actual_connection = NULL;
3021
static struct connection *all_connections = NULL;
3122

3223
#ifdef ENABLE_THREAD_SAFETY
33-
static void
24+
NON_EXEC_STATIC void
3425
ecpg_actual_connection_init(void)
3526
{
3627
pthread_key_create(&actual_connection_key, NULL);
@@ -39,13 +30,7 @@ ecpg_actual_connection_init(void)
3930
void
4031
ecpg_pthreads_init(void)
4132
{
42-
#ifndef WIN32
4333
pthread_once(&actual_connection_key_once, ecpg_actual_connection_init);
44-
#else
45-
static long has_run = 0;
46-
if (InterlockedCompareExchange(&has_run, 1, 0) == 0)
47-
ecpg_actual_connection_init();
48-
#endif
4934
}
5035
#endif
5136

@@ -134,6 +119,7 @@ ecpg_finish(struct connection * act)
134119
struct ECPGtype_information_cache *cache,
135120
*ptr;
136121

122+
ECPGdeallocate_all_conn(0, ECPG_COMPAT_PGSQL, act);
137123
PQfinish(act->connection);
138124

139125
/*

src/interfaces/ecpg/ecpglib/extern.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/extern.h,v 1.27 2007/09/26 10:57:00 meskes Exp $ */
1+
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/extern.h,v 1.28 2007/09/30 11:38:48 meskes Exp $ */
22

33
#ifndef _ECPG_LIB_EXTERN_H
44
#define _ECPG_LIB_EXTERN_H
@@ -146,6 +146,7 @@ bool ECPGcheck_PQresult(PGresult *, int, PGconn *, enum COMPAT_MODE);
146146
void ECPGraise(int line, int code, const char *sqlstate, const char *str);
147147
void ECPGraise_backend(int line, PGresult *result, PGconn *conn, int compat);
148148
char *ECPGprepared(const char *, struct connection *, int);
149+
bool ECPGdeallocate_all_conn(int lineno, enum COMPAT_MODE c, struct connection *conn);
149150

150151
/* SQLSTATE values generated or processed by ecpglib (intentionally
151152
* not exported -- users should refer to the codes directly) */

src/interfaces/ecpg/ecpglib/memory.c

Lines changed: 62 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/memory.c,v 1.8 2006/11/08 10:46:47 meskes Exp $ */
1+
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/memory.c,v 1.9 2007/09/30 11:38:48 meskes Exp $ */
22

33
#define POSTGRES_ECPG_INTERNAL
44
#include "postgres_fe.h"
55

6+
#include "ecpg-pthread-win32.h"
67
#include "ecpgtype.h"
78
#include "ecpglib.h"
89
#include "ecpgerrno.h"
@@ -25,7 +26,6 @@ ECPGalloc(long size, int lineno)
2526
return NULL;
2627
}
2728

28-
memset(new, '\0', size);
2929
return (new);
3030
}
3131

@@ -62,53 +62,92 @@ ECPGstrdup(const char *string, int lineno)
6262
}
6363

6464
/* keep a list of memory we allocated for the user */
65-
static struct auto_mem
65+
struct auto_mem
6666
{
6767
void *pointer;
6868
struct auto_mem *next;
69-
} *auto_allocs = NULL;
69+
};
70+
71+
#ifdef ENABLE_THREAD_SAFETY
72+
static pthread_key_t auto_mem_key;
73+
#ifndef WIN32
74+
static pthread_once_t auto_mem_once = PTHREAD_ONCE_INIT;
75+
#endif
76+
77+
static void
78+
auto_mem_destructor(void *arg)
79+
{
80+
ECPGfree_auto_mem();
81+
}
82+
83+
NON_EXEC_STATIC void
84+
auto_mem_key_init(void)
85+
{
86+
pthread_key_create(&auto_mem_key, auto_mem_destructor);
87+
}
88+
89+
static struct auto_mem *
90+
get_auto_allocs(void)
91+
{
92+
pthread_once(&auto_mem_once, auto_mem_key_init);
93+
return (struct auto_mem *) pthread_getspecific(auto_mem_key);
94+
}
95+
96+
static void
97+
set_auto_allocs(struct auto_mem *am)
98+
{
99+
pthread_setspecific(auto_mem_key, am);
100+
}
101+
102+
#else
103+
static struct auto_mem *auto_allocs = NULL;
104+
#define get_auto_allocs() (auto_allocs)
105+
#define set_auto_allocs(am) do { auto_allocs = (am); } while(0)
106+
#endif
70107

71108
void
72109
ECPGadd_mem(void *ptr, int lineno)
73110
{
74111
struct auto_mem *am = (struct auto_mem *) ECPGalloc(sizeof(struct auto_mem), lineno);
75112

76113
am->pointer = ptr;
77-
am->next = auto_allocs;
78-
auto_allocs = am;
114+
am->next = get_auto_allocs();
115+
set_auto_allocs(am);
79116
}
80117

81118
void
82119
ECPGfree_auto_mem(void)
83120
{
84-
struct auto_mem *am;
121+
struct auto_mem *am = get_auto_allocs();
85122

86123
/* free all memory we have allocated for the user */
87-
for (am = auto_allocs; am;)
124+
if (am)
88125
{
89-
struct auto_mem *act = am;
90-
91-
am = am->next;
92-
ECPGfree(act->pointer);
93-
ECPGfree(act);
126+
do
127+
{
128+
struct auto_mem *act = am;
129+
am = am->next;
130+
ECPGfree(act->pointer);
131+
ECPGfree(act);
132+
} while(am);
133+
set_auto_allocs(NULL);
94134
}
95-
96-
auto_allocs = NULL;
97135
}
98136

99137
void
100138
ECPGclear_auto_mem(void)
101139
{
102-
struct auto_mem *am;
140+
struct auto_mem *am = get_auto_allocs();
103141

104142
/* only free our own structure */
105-
for (am = auto_allocs; am;)
143+
if (am)
106144
{
107-
struct auto_mem *act = am;
108-
109-
am = am->next;
110-
ECPGfree(act);
145+
do
146+
{
147+
struct auto_mem *act = am;
148+
am = am->next;
149+
ECPGfree(act);
150+
} while(am);
151+
set_auto_allocs(NULL);
111152
}
112-
113-
auto_allocs = NULL;
114153
}

src/interfaces/ecpg/ecpglib/misc.c

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
1-
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/misc.c,v 1.36 2007/08/14 10:01:52 meskes Exp $ */
1+
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/misc.c,v 1.37 2007/09/30 11:38:48 meskes Exp $ */
22

33
#define POSTGRES_ECPG_INTERNAL
44
#include "postgres_fe.h"
55

66
#include <limits.h>
77
#include <unistd.h>
8-
#ifdef ENABLE_THREAD_SAFETY
9-
#ifndef WIN32
10-
#include <pthread.h>
11-
#else
128
#include "ecpg-pthread-win32.h"
13-
#endif
14-
#endif
159
#include "ecpgtype.h"
1610
#include "ecpglib.h"
1711
#include "ecpgerrno.h"
@@ -62,11 +56,9 @@ static struct sqlca_t sqlca_init =
6256
};
6357

6458
#ifdef ENABLE_THREAD_SAFETY
65-
#ifndef WIN32
6659
static pthread_key_t sqlca_key;
60+
#ifndef WIN32
6761
static pthread_once_t sqlca_key_once = PTHREAD_ONCE_INIT;
68-
#else
69-
static DWORD sqlca_key;
7062
#endif
7163
#else
7264
static struct sqlca_t sqlca =
@@ -98,13 +90,8 @@ static struct sqlca_t sqlca =
9890
#endif
9991

10092
#ifdef ENABLE_THREAD_SAFETY
101-
#ifndef WIN32
102-
static pthread_mutex_t debug_mutex = PTHREAD_MUTEX_INITIALIZER;
103-
static pthread_mutex_t debug_init_mutex = PTHREAD_MUTEX_INITIALIZER;
104-
#else
105-
static HANDLE debug_mutex = INVALID_HANDLE_VALUE;
106-
static HANDLE debug_init_mutex = INVALID_HANDLE_VALUE;
107-
#endif /* WIN32 */
93+
NON_EXEC_STATIC pthread_mutex_t debug_mutex = PTHREAD_MUTEX_INITIALIZER;
94+
NON_EXEC_STATIC pthread_mutex_t debug_init_mutex = PTHREAD_MUTEX_INITIALIZER;
10895
#endif
10996
static int simple_debug = 0;
11097
static FILE *debugstream = NULL;
@@ -135,11 +122,10 @@ ECPGinit(const struct connection * con, const char *connection_name, const int l
135122
static void
136123
ecpg_sqlca_key_destructor(void *arg)
137124
{
138-
if (arg != NULL)
139-
free(arg); /* sqlca structure allocated in ECPGget_sqlca */
125+
free(arg); /* sqlca structure allocated in ECPGget_sqlca */
140126
}
141127

142-
static void
128+
NON_EXEC_STATIC void
143129
ecpg_sqlca_key_init(void)
144130
{
145131
pthread_key_create(&sqlca_key, ecpg_sqlca_key_destructor);
@@ -151,13 +137,8 @@ ECPGget_sqlca(void)
151137
{
152138
#ifdef ENABLE_THREAD_SAFETY
153139
struct sqlca_t *sqlca;
154-
#ifdef WIN32
155-
static long has_run = 0;
156-
if (InterlockedCompareExchange(&has_run, 1, 0) == 0)
157-
ecpg_sqlca_key_init();
158-
#else
140+
159141
pthread_once(&sqlca_key_once, ecpg_sqlca_key_init);
160-
#endif
161142

162143
sqlca = pthread_getspecific(sqlca_key);
163144
if (sqlca == NULL)
@@ -263,22 +244,13 @@ ECPGlog(const char *format,...)
263244
va_list ap;
264245
struct sqlca_t *sqlca = ECPGget_sqlca();
265246

266-
#ifdef ENABLE_THREAD_SAFETY
267-
pthread_mutex_lock(&debug_mutex);
268-
#endif
269-
270247
if (simple_debug)
271248
{
272249
int bufsize = strlen(format) + 100;
273250
char *f = (char *) malloc(bufsize);
274251

275252
if (f == NULL)
276-
{
277-
#ifdef ENABLE_THREAD_SAFETY
278-
pthread_mutex_unlock(&debug_mutex);
279-
#endif
280253
return;
281-
}
282254

283255
/*
284256
* regression tests set this environment variable to get the same
@@ -289,6 +261,10 @@ ECPGlog(const char *format,...)
289261
else
290262
snprintf(f, bufsize, "[%d]: %s", (int) getpid(), format);
291263

264+
#ifdef ENABLE_THREAD_SAFETY
265+
pthread_mutex_lock(&debug_mutex);
266+
#endif
267+
292268
va_start(ap, format);
293269
vfprintf(debugstream, f, ap);
294270
va_end(ap);
@@ -300,12 +276,12 @@ ECPGlog(const char *format,...)
300276

301277
fflush(debugstream);
302278

303-
ECPGfree(f);
304-
}
305-
306279
#ifdef ENABLE_THREAD_SAFETY
307-
pthread_mutex_unlock(&debug_mutex);
280+
pthread_mutex_unlock(&debug_mutex);
308281
#endif
282+
283+
free(f);
284+
}
309285
}
310286

311287
void
@@ -437,3 +413,25 @@ ECPGis_noind_null(enum ECPGttype type, void *ptr)
437413

438414
return false;
439415
}
416+
417+
#ifdef WIN32
418+
419+
/*
420+
* Initialize mutexes and call init-once functions on loading.
421+
*/
422+
423+
BOOL WINAPI
424+
DllMain(HANDLE module, DWORD reason, LPVOID reserved)
425+
{
426+
if (reason == DLL_PROCESS_ATTACH)
427+
{
428+
connections_mutex = CreateMutex(NULL, FALSE, NULL);
429+
debug_mutex = CreateMutex(NULL, FALSE, NULL);
430+
debug_init_mutex = CreateMutex(NULL, FALSE, NULL);
431+
auto_mem_key_init();
432+
ecpg_actual_connection_init();
433+
ecpg_sqlca_key_init();
434+
}
435+
return TRUE;
436+
}
437+
#endif

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy