1- /* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.6 2003/06/13 10:50:57 meskes Exp $ */
1+ /* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.7 2003/06/15 04:07:58 momjian Exp $ */
22
3+ #define POSTGRES_ECPG_INTERNAL
34#include "postgres_fe.h"
45
6+ #ifdef USE_THREADS
7+ #include <pthread.h>
8+ #endif
59#include "ecpgtype.h"
610#include "ecpglib.h"
711#include "ecpgerrno.h"
812#include "extern.h"
913#include "sqlca.h"
1014
11- static struct connection * all_connections = NULL ,
12- * actual_connection = NULL ;
15+ #ifdef USE_THREADS
16+ static pthread_mutex_t connections_mutex = PTHREAD_MUTEX_INITIALIZER ;
17+ #endif
18+ static struct connection * all_connections = NULL ;
19+ static struct connection * actual_connection = NULL ;
1320
1421struct connection *
1522ECPGget_connection (const char * connection_name )
1623{
17- struct connection * con = all_connections ;
24+ struct connection * ret = NULL ;
25+
26+ #ifdef USE_THREADS
27+ pthread_mutex_lock (& connections_mutex );
28+ #endif
29+
30+ if ( (connection_name == NULL ) || (strcmp (connection_name , "CURRENT" ) == 0 ) )
31+ {
32+ ret = actual_connection ;
33+ }
34+ else
35+ {
36+ struct connection * con ;
37+
38+ for ( con = all_connections ; con != NULL ; con = con -> next )
39+ {
40+ if ( strcmp (connection_name , con -> name ) == 0 )
41+ break ;
42+ }
43+ ret = con ;
44+ }
1845
19- if (connection_name == NULL || strcmp (connection_name , "CURRENT" ) == 0 )
20- return actual_connection ;
46+ #ifdef USE_THREADS
47+ pthread_mutex_unlock (& connections_mutex );
48+ #endif
2149
22- for (; con && strcmp (connection_name , con -> name ) != 0 ; con = con -> next );
23- if (con )
24- return con ;
25- else
26- return NULL ;
50+ return ( ret );
2751}
2852
2953static void
@@ -37,6 +61,10 @@ ecpg_finish(struct connection * act)
3761 ECPGlog ("ecpg_finish: finishing %s.\n" , act -> name );
3862 PQfinish (act -> connection );
3963
64+ /* no need to lock connections_mutex - we're always called
65+ by ECPGdisconnect or ECPGconnect, which are holding
66+ the lock */
67+
4068 /* remove act from the list */
4169 if (act == all_connections )
4270 all_connections = act -> next ;
@@ -118,17 +146,18 @@ ECPGsetconn(int lineno, const char *connection_name)
118146static void
119147ECPGnoticeProcessor_raise (int code , const char * message )
120148{
121- sqlca .sqlcode = code ;
122- strncpy (sqlca .sqlerrm .sqlerrmc , message , sizeof (sqlca .sqlerrm .sqlerrmc ));
123- sqlca .sqlerrm .sqlerrmc [sizeof (sqlca .sqlerrm .sqlerrmc ) - 1 ] = 0 ;
124- sqlca .sqlerrm .sqlerrml = strlen (sqlca .sqlerrm .sqlerrmc );
149+ struct sqlca_t * sqlca = ECPGget_sqlca ();
150+ sqlca -> sqlcode = code ;
151+ strncpy (sqlca -> sqlerrm .sqlerrmc , message , sizeof (sqlca -> sqlerrm .sqlerrmc ));
152+ sqlca -> sqlerrm .sqlerrmc [sizeof (sqlca -> sqlerrm .sqlerrmc ) - 1 ] = 0 ;
153+ sqlca -> sqlerrm .sqlerrml = strlen (sqlca -> sqlerrm .sqlerrmc );
125154
126155 /* remove trailing newline */
127- if (sqlca . sqlerrm .sqlerrml
128- && sqlca . sqlerrm .sqlerrmc [sqlca . sqlerrm .sqlerrml - 1 ] == '\n' )
156+ if (sqlca -> sqlerrm .sqlerrml
157+ && sqlca -> sqlerrm .sqlerrmc [sqlca -> sqlerrm .sqlerrml - 1 ] == '\n' )
129158 {
130- sqlca . sqlerrm .sqlerrmc [sqlca . sqlerrm .sqlerrml - 1 ] = 0 ;
131- sqlca . sqlerrm .sqlerrml -- ;
159+ sqlca -> sqlerrm .sqlerrmc [sqlca -> sqlerrm .sqlerrml - 1 ] = 0 ;
160+ sqlca -> sqlerrm .sqlerrml -- ;
132161 }
133162
134163 ECPGlog ("raising sqlcode %d\n" , code );
@@ -141,6 +170,8 @@ ECPGnoticeProcessor_raise(int code, const char *message)
141170static void
142171ECPGnoticeProcessor (void * arg , const char * message )
143172{
173+ struct sqlca_t * sqlca = ECPGget_sqlca ();
174+
144175 /* these notices raise an error */
145176 if (strncmp (message , "WARNING: " , 9 ))
146177 {
@@ -245,22 +276,23 @@ ECPGnoticeProcessor(void *arg, const char *message)
245276 if (strstr (message , "cannot be rolled back" ))
246277 return ;
247278
248- /* these and other unmentioned should set sqlca. sqlwarn[2] */
279+ /* these and other unmentioned should set sqlca-> sqlwarn[2] */
249280 /* WARNING: The ':' operator is deprecated. Use exp(x) instead. */
250281 /* WARNING: Rel *: Uninitialized page 0 - fixing */
251282 /* WARNING: PortalHeapMemoryFree: * not in alloc set! */
252283 /* WARNING: Too old parent tuple found - can't continue vc_repair_frag */
253284 /* WARNING: identifier "*" will be truncated to "*" */
254285 /* WARNING: InvalidateSharedInvalid: cache state reset */
255286 /* WARNING: RegisterSharedInvalid: SI buffer overflow */
256- sqlca . sqlwarn [2 ] = 'W' ;
257- sqlca . sqlwarn [0 ] = 'W' ;
287+ sqlca -> sqlwarn [2 ] = 'W' ;
288+ sqlca -> sqlwarn [0 ] = 'W' ;
258289}
259290
260291/* this contains some quick hacks, needs to be cleaned up, but it works */
261292bool
262293ECPGconnect (int lineno , const char * name , const char * user , const char * passwd , const char * connection_name , int autocommit )
263294{
295+ struct sqlca_t * sqlca = ECPGget_sqlca ();
264296 struct connection * this ;
265297 char * dbname = strdup (name ),
266298 * host = NULL ,
@@ -269,7 +301,7 @@ ECPGconnect(int lineno, const char *name, const char *user, const char *passwd,
269301 * realname = NULL ,
270302 * options = NULL ;
271303
272- ECPGinit_sqlca ();
304+ ECPGinit_sqlca (sqlca );
273305
274306 if ((this = (struct connection * ) ECPGalloc (sizeof (struct connection ), lineno )) == NULL )
275307 return false;
@@ -394,6 +426,9 @@ ECPGconnect(int lineno, const char *name, const char *user, const char *passwd,
394426 realname = strdup (dbname );
395427
396428 /* add connection to our list */
429+ #ifdef USE_THREADS
430+ pthread_mutex_lock (& connections_mutex );
431+ #endif
397432 if (connection_name != NULL )
398433 this -> name = ECPGstrdup (connection_name , lineno );
399434 else
@@ -424,6 +459,9 @@ ECPGconnect(int lineno, const char *name, const char *user, const char *passwd,
424459
425460 set_backend_err (errmsg , lineno );
426461 ecpg_finish (this );
462+ #ifdef USE_THREADS
463+ pthread_mutex_unlock (& connections_mutex );
464+ #endif
427465 ECPGlog ("connect: could not open database %s on %s port %s %s%s%s%s in line %d\n\t%s\n" ,
428466 db ,
429467 host ? host : "<DEFAULT>" ,
@@ -445,6 +483,9 @@ ECPGconnect(int lineno, const char *name, const char *user, const char *passwd,
445483 ECPGfree (dbname );
446484 return false;
447485 }
486+ #ifdef USE_THREADS
487+ pthread_mutex_unlock (& connections_mutex );
488+ #endif
448489
449490 if (host )
450491 ECPGfree (host );
@@ -468,11 +509,16 @@ ECPGconnect(int lineno, const char *name, const char *user, const char *passwd,
468509bool
469510ECPGdisconnect (int lineno , const char * connection_name )
470511{
512+ struct sqlca_t * sqlca = ECPGget_sqlca ();
471513 struct connection * con ;
472514
515+ #ifdef USE_THREADS
516+ pthread_mutex_lock (& connections_mutex );
517+ #endif
518+
473519 if (strcmp (connection_name , "ALL" ) == 0 )
474520 {
475- ECPGinit_sqlca ();
521+ ECPGinit_sqlca (sqlca );
476522 for (con = all_connections ; con ;)
477523 {
478524 struct connection * f = con ;
@@ -486,10 +532,19 @@ ECPGdisconnect(int lineno, const char *connection_name)
486532 con = ECPGget_connection (connection_name );
487533
488534 if (!ECPGinit (con , connection_name , lineno ))
489- return (false);
535+ {
536+ #ifdef USE_THREADS
537+ pthread_mutex_unlock (& connections_mutex );
538+ #endif
539+ return (false);
540+ }
490541 else
491- ecpg_finish (con );
542+ ecpg_finish (con );
492543 }
493544
545+ #ifdef USE_THREADS
546+ pthread_mutex_unlock (& connections_mutex );
547+ #endif
548+
494549 return true;
495550}
0 commit comments