mirror of https://github.com/postgres/postgres
to get memory allocation thread-safe. He also did some cleaning up.REL8_3_STABLE
parent
ae57efed4a
commit
60e83cec57
@ -1,16 +1,56 @@ |
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/include/ecpg-pthread-win32.h,v 1.1 2007/03/29 12:02:24 meskes Exp $ */ |
||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/include/ecpg-pthread-win32.h,v 1.2 2007/09/30 11:38:48 meskes Exp $ */ |
||||
/*
|
||||
* pthread mapping macros for win32 native thread implementation |
||||
*/ |
||||
#ifndef _ECPG_PTHREAD_WIN32_H |
||||
#define _ECPG_PTHREAD_WIN32_H |
||||
#define pthread_mutex_lock(x) do { \ |
||||
if (*x == INVALID_HANDLE_VALUE) \
|
||||
*x = CreateMutex(NULL, FALSE, NULL); \
|
||||
WaitForSingleObject(*x, INFINITE); \
|
||||
} while (0); |
||||
#define pthread_mutex_unlock(x) ReleaseMutex(*x) |
||||
#define pthread_getspecific(x) TlsGetValue(x) |
||||
#define pthread_setspecific(x,y) TlsSetValue(x,y) |
||||
#define pthread_key_create(x,y) *x = TlsAlloc(); |
||||
#endif |
||||
|
||||
#ifdef ENABLE_THREAD_SAFETY |
||||
|
||||
#ifndef WIN32 |
||||
|
||||
#include <pthread.h> |
||||
#define NON_EXEC_STATIC static |
||||
|
||||
#else |
||||
|
||||
#define NON_EXEC_STATIC |
||||
|
||||
typedef HANDLE pthread_mutex_t; |
||||
typedef DWORD pthread_key_t; |
||||
|
||||
#define PTHREAD_MUTEX_INITIALIZER INVALID_HANDLE_VALUE |
||||
|
||||
#define pthread_mutex_lock(mutex) \ |
||||
WaitForSingleObject(*(mutex), INFINITE); |
||||
|
||||
#define pthread_mutex_unlock(mutex) \ |
||||
ReleaseMutex(*(mutex)) |
||||
|
||||
#define pthread_getspecific(key) \ |
||||
TlsGetValue((key)) |
||||
|
||||
#define pthread_setspecific(key, value) \ |
||||
TlsSetValue((key), (value)) |
||||
|
||||
/* FIXME: destructor is never called in Win32. */ |
||||
#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 BOOL WINAPI DllMain(HANDLE module, DWORD reason, LPVOID reserved); |
||||
|
||||
#endif /* WIN32 */ |
||||
|
||||
#endif /* ENABLE_THREAD_SAFETY */ |
||||
|
||||
#endif /* _ECPG_PTHREAD_WIN32_H */ |
||||
|
@ -0,0 +1,218 @@ |
||||
/* Processed by ecpg (regression mode) */ |
||||
/* These include files are added by the preprocessor */ |
||||
#include <ecpgtype.h> |
||||
#include <ecpglib.h> |
||||
#include <ecpgerrno.h> |
||||
#include <sqlca.h> |
||||
/* End of automatic include section */ |
||||
#define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y)) |
||||
|
||||
#line 1 "alloc.pgc" |
||||
#include <stdlib.h> |
||||
#include "ecpg_config.h" |
||||
|
||||
#ifndef ENABLE_THREAD_SAFETY |
||||
int |
||||
main(void) |
||||
{ |
||||
printf("No threading enabled.\n"); |
||||
return 0; |
||||
} |
||||
#else |
||||
#ifdef WIN32 |
||||
#define WIN32_LEAN_AND_MEAN |
||||
#include <windows.h> |
||||
#include <process.h> |
||||
#else |
||||
#include <pthread.h> |
||||
#endif |
||||
#include <stdio.h> |
||||
|
||||
#define THREADS 16 |
||||
#define REPEATS 50 |
||||
|
||||
|
||||
#line 1 "sqlca.h" |
||||
#ifndef POSTGRES_SQLCA_H |
||||
#define POSTGRES_SQLCA_H |
||||
|
||||
#ifndef PGDLLIMPORT |
||||
#if defined(WIN32) || defined(__CYGWIN__) |
||||
#define PGDLLIMPORT __declspec (dllimport) |
||||
#else |
||||
#define PGDLLIMPORT |
||||
#endif /* __CYGWIN__ */ |
||||
#endif /* PGDLLIMPORT */ |
||||
|
||||
#define SQLERRMC_LEN 150 |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" |
||||
{ |
||||
#endif |
||||
|
||||
struct sqlca_t |
||||
{ |
||||
char sqlcaid[8]; |
||||
long sqlabc; |
||||
long sqlcode; |
||||
struct |
||||
{ |
||||
int sqlerrml; |
||||
char sqlerrmc[SQLERRMC_LEN]; |
||||
} sqlerrm; |
||||
char sqlerrp[8]; |
||||
long sqlerrd[6]; |
||||
/* Element 0: empty */ |
||||
/* 1: OID of processed tuple if applicable */ |
||||
/* 2: number of rows processed */ |
||||
/* after an INSERT, UPDATE or */ |
||||
/* DELETE statement */ |
||||
/* 3: empty */ |
||||
/* 4: empty */ |
||||
/* 5: empty */ |
||||
char sqlwarn[8]; |
||||
/* Element 0: set to 'W' if at least one other is 'W' */ |
||||
/* 1: if 'W' at least one character string */ |
||||
/* value was truncated when it was */ |
||||
/* stored into a host variable. */ |
||||
|
||||
/*
|
||||
* 2: if 'W' a (hopefully) non-fatal notice occurred |
||||
*/ /* 3: empty */ |
||||
/* 4: empty */ |
||||
/* 5: empty */ |
||||
/* 6: empty */ |
||||
/* 7: empty */ |
||||
|
||||
char sqlstate[5]; |
||||
}; |
||||
|
||||
struct sqlca_t *ECPGget_sqlca(void); |
||||
|
||||
#ifndef POSTGRES_ECPG_INTERNAL |
||||
#define sqlca (*ECPGget_sqlca()) |
||||
#endif |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif |
||||
|
||||
#line 24 "alloc.pgc" |
||||
|
||||
|
||||
#line 1 "regression.h" |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#line 25 "alloc.pgc" |
||||
|
||||
|
||||
/* exec sql whenever sqlerror sqlprint ; */ |
||||
#line 27 "alloc.pgc" |
||||
|
||||
/* exec sql whenever not found sqlprint ; */ |
||||
#line 28 "alloc.pgc" |
||||
|
||||
|
||||
#ifdef WIN32 |
||||
static unsigned STDCALL fn(void* arg) |
||||
#else |
||||
static void* fn(void* arg) |
||||
#endif |
||||
{ |
||||
int i; |
||||
|
||||
/* exec sql begin declare section */ |
||||
|
||||
|
||||
|
||||
|
||||
#line 39 "alloc.pgc" |
||||
int value ; |
||||
|
||||
#line 40 "alloc.pgc" |
||||
char name [ 100 ] ; |
||||
|
||||
#line 41 "alloc.pgc" |
||||
char ** r = NULL ; |
||||
/* exec sql end declare section */ |
||||
#line 42 "alloc.pgc" |
||||
|
||||
|
||||
value = (int)arg; |
||||
sprintf(name, "Connection: %d", value); |
||||
|
||||
{ ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , name, 0);
|
||||
#line 47 "alloc.pgc" |
||||
|
||||
if (sqlca.sqlcode < 0) sqlprint();} |
||||
#line 47 "alloc.pgc" |
||||
|
||||
{ ECPGsetcommit(__LINE__, "on", NULL); |
||||
#line 48 "alloc.pgc" |
||||
|
||||
if (sqlca.sqlcode < 0) sqlprint();} |
||||
#line 48 "alloc.pgc" |
||||
|
||||
for (i = 1; i <= REPEATS; ++i) |
||||
{ |
||||
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select relname from pg_class where relname = 'pg_class' ", ECPGt_EOIT,
|
||||
ECPGt_char,&(r),(long)0,(long)0,(1)*sizeof(char),
|
||||
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); |
||||
#line 51 "alloc.pgc" |
||||
|
||||
if (sqlca.sqlcode == ECPG_NOT_FOUND) sqlprint(); |
||||
#line 51 "alloc.pgc" |
||||
|
||||
if (sqlca.sqlcode < 0) sqlprint();} |
||||
#line 51 "alloc.pgc" |
||||
|
||||
free(r); |
||||
r = NULL; |
||||
} |
||||
{ ECPGdisconnect(__LINE__, name); |
||||
#line 55 "alloc.pgc" |
||||
|
||||
if (sqlca.sqlcode < 0) sqlprint();} |
||||
#line 55 "alloc.pgc" |
||||
|
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int main (int argc, char** argv) |
||||
{ |
||||
int i; |
||||
#ifdef WIN32 |
||||
HANDLE threads[THREADS]; |
||||
#else |
||||
pthread_t threads[THREADS]; |
||||
#endif |
||||
|
||||
#ifdef WIN32 |
||||
for (i = 0; i < THREADS; ++i) |
||||
{ |
||||
unsigned id; |
||||
threads[i] = (HANDLE)_beginthreadex(NULL, 0, fn, (void*)i, 0, &id); |
||||
} |
||||
|
||||
WaitForMultipleObjects(THREADS, threads, TRUE, INFINITE); |
||||
for (i = 0; i < THREADS; ++i) |
||||
CloseHandle(threads[i]); |
||||
#else |
||||
for (i = 0; i < THREADS; ++i) |
||||
pthread_create(&threads[i], NULL, fn, (void*)i); |
||||
for (i = 0; i < THREADS; ++i) |
||||
pthread_join(threads[i], NULL); |
||||
#endif |
||||
|
||||
return 0; |
||||
} |
||||
#endif |
||||
|
@ -0,0 +1 @@ |
||||
No threading enabled. |
Loading…
Reference in new issue