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 |
* pthread mapping macros for win32 native thread implementation |
||||||
*/ |
*/ |
||||||
#ifndef _ECPG_PTHREAD_WIN32_H |
#ifndef _ECPG_PTHREAD_WIN32_H |
||||||
#define _ECPG_PTHREAD_WIN32_H |
#define _ECPG_PTHREAD_WIN32_H |
||||||
#define pthread_mutex_lock(x) do { \ |
|
||||||
if (*x == INVALID_HANDLE_VALUE) \
|
#ifdef ENABLE_THREAD_SAFETY |
||||||
*x = CreateMutex(NULL, FALSE, NULL); \
|
|
||||||
WaitForSingleObject(*x, INFINITE); \
|
#ifndef WIN32 |
||||||
} while (0); |
|
||||||
#define pthread_mutex_unlock(x) ReleaseMutex(*x) |
#include <pthread.h> |
||||||
#define pthread_getspecific(x) TlsGetValue(x) |
#define NON_EXEC_STATIC static |
||||||
#define pthread_setspecific(x,y) TlsSetValue(x,y) |
|
||||||
#define pthread_key_create(x,y) *x = TlsAlloc(); |
#else |
||||||
#endif |
|
||||||
|
#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