Re: ECPG - Remove need for "AT connection" when using threads

From: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
To: Lee Kindness <lkindness(at)csl(dot)co(dot)uk>
Cc: Michael Meskes <meskes(at)postgresql(dot)org>, pgsql-patches(at)postgresql(dot)org
Subject: Re: ECPG - Remove need for "AT connection" when using threads
Date: 2004-03-15 16:27:48
Message-ID: 200403151627.i2FGRmV17825@candle.pha.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers pgsql-patches


Patch applied. File added. Thanks.

---------------------------------------------------------------------------

Lee Kindness wrote:
Content-Description: message body text

> The "cvs add" of test_thread_implicit.pgc seems to have been missed,
> i've attached this again.
>
> Additionally I include a small patch to remove mutex locking when a
> DEFAULT/NULL connection is being retrieved. This is consistent with
> libpq.
>
> Thanks, L.
>
> Michael Meskes writes:
> > On Sun, Mar 14, 2004 at 09:11:27AM -0500, Bruce Momjian wrote:
> > > > I just applied this patch and the last one.
> > >
> > > I assume you mean you applied:
> > >
> > > Update tests & memory leak fix
> > >
> > > and
> > >
> > > ECPG - Remove need for "AT connection" when using threads
> >
> > Yes. Sorry, should have said so.
> >
> > Michael
>

> /*
> * Thread test program
> * by Lee Kindness.
> */
>
> /* #define ECPGDEBUG */
>
> #include <pthread.h>
> #include <stdlib.h>
>
> void *test_thread(void *arg);
>
> EXEC SQL BEGIN DECLARE SECTION;
> char *l_dbname;
> EXEC SQL END DECLARE SECTION;
> int nthreads = 2;
> int iterations = 10;
>
> int main(int argc, char *argv[])
> {
> #ifdef ECPGDEBUG
> char debugfilename[] = "thread_test_implicit.log";
> FILE *debugfile;
> #endif
> pthread_t *threads;
> int n;
> EXEC SQL BEGIN DECLARE SECTION;
> int l_rows;
> EXEC SQL END DECLARE SECTION;
>
> /* parse command line arguments */
> if( (argc < 2) || (argc > 4) )
> {
> fprintf(stderr, "Usage: %s dbname [threads] [iterations_per_thread]\n", argv[0]);
> return( 1 );
> }
> l_dbname = argv[1];
> if( argc >= 3 )
> nthreads = atoi(argv[2]);
> if( argc == 4 )
> iterations = atoi(argv[3]);
>
> /* open ECPG debug log? */
> #ifdef ECPGDEBUG
> debugfile = fopen(debugfilename, "w");
> if( debugfile != NULL )
> ECPGdebug(1, debugfile);
> else
> fprintf(stderr, "Cannot open ECPG debug log: %s\n", debugfilename);
> #endif
>
> /* setup test_thread table */
> EXEC SQL CONNECT TO:l_dbname;
> EXEC SQL DROP TABLE test_thread; /* DROP might fail */
> EXEC SQL COMMIT;
> EXEC SQL CREATE TABLE
> test_thread(tstamp TIMESTAMP NOT NULL DEFAULT CAST(timeofday() AS TIMESTAMP),
> thread TEXT NOT NULL,
> iteration INTEGER NOT NULL,
> PRIMARY KEY(thread, iteration));
> EXEC SQL COMMIT;
> EXEC SQL DISCONNECT;
>
> /* create, and start, threads */
> threads = calloc(nthreads, sizeof(pthread_t));
> if( threads == NULL )
> {
> fprintf(stderr, "Cannot alloc memory\n");
> return( 1 );
> }
> for( n = 0; n < nthreads; n++ )
> {
> pthread_create(&threads[n], NULL, test_thread, (void *)n + 1);
> }
>
> /* wait for thread completion */
> for( n = 0; n < nthreads; n++ )
> {
> pthread_join(threads[n], NULL);
> }
> free(threads);
>
> /* and check results */
> EXEC SQL CONNECT TO :l_dbname;
> EXEC SQL SELECT COUNT(*) INTO :l_rows FROM test_thread;
> EXEC SQL COMMIT;
> EXEC SQL DISCONNECT;
> if( l_rows == (nthreads * iterations) )
> printf("\nSuccess.\n");
> else
> printf("\nERROR: Failure - expecting %d rows, got %d.\n", nthreads * iterations, l_rows);
>
> /* close ECPG debug log? */
> #ifdef ECPGDEBUG
> if( debugfile != NULL )
> {
> ECPGdebug(0, debugfile);
> fclose(debugfile);
> }
> #endif
>
> return( 0 );
> }
>
> void *test_thread(void *arg)
> {
> long threadnum = (long)arg;
> EXEC SQL BEGIN DECLARE SECTION;
> int l_i;
> char l_connection[128];
> EXEC SQL END DECLARE SECTION;
>
> /* build up connection name, and connect to database */
> snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum);
> EXEC SQL WHENEVER sqlerror sqlprint;
> EXEC SQL CONNECT TO :l_dbname AS :l_connection;
> if( sqlca.sqlcode != 0 )
> {
> printf("%s: ERROR: cannot connect to database!\n", l_connection);
> return( NULL );
> }
> EXEC SQL BEGIN;
>
> /* insert into test_thread table */
> for( l_i = 1; l_i <= iterations; l_i++ )
> {
> printf("%s: inserting %d\n", l_connection, l_i);
> EXEC SQL INSERT INTO test_thread(thread, iteration) VALUES(:l_connection, :l_i);
> if( sqlca.sqlcode == 0 )
> printf("%s: insert done\n", l_connection);
> else
> printf("%s: ERROR: insert failed!\n", l_connection);
> }
>
> /* all done */
> EXEC SQL COMMIT;
> EXEC SQL DISCONNECT :l_connection;
> printf("%s: done!\n", l_connection);
> return( NULL );
> }

> Index: src/interfaces/ecpg/ecpglib/connect.c
> ===================================================================
> RCS file: /projects/cvsroot/pgsql-server/src/interfaces/ecpg/ecpglib/connect.c,v
> retrieving revision 1.20
> diff -c -r1.20 connect.c
> *** src/interfaces/ecpg/ecpglib/connect.c 14 Mar 2004 12:16:29 -0000 1.20
> --- src/interfaces/ecpg/ecpglib/connect.c 15 Mar 2004 16:17:36 -0000
> ***************
> *** 62,79 ****
> {
> struct connection *ret = NULL;
>
> #ifdef ENABLE_THREAD_SAFETY
> ! pthread_mutex_lock(&connections_mutex);
> #endif
>
> ! ret = ecpg_get_connection_nr(connection_name);
>
> #ifdef ENABLE_THREAD_SAFETY
> ! pthread_mutex_unlock(&connections_mutex);
> #endif
>
> return (ret);
> -
> }
>
> static void
> --- 62,89 ----
> {
> struct connection *ret = NULL;
>
> + if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
> + {
> #ifdef ENABLE_THREAD_SAFETY
> ! ret = pthread_getspecific(actual_connection_key);
> ! #else
> ! ret = actual_connection;
> ! #endif
> ! }
> ! else
> ! {
> ! #ifdef ENABLE_THREAD_SAFETY
> ! pthread_mutex_lock(&connections_mutex);
> #endif
>
> ! ret = ecpg_get_connection_nr(connection_name);
>
> #ifdef ENABLE_THREAD_SAFETY
> ! pthread_mutex_unlock(&connections_mutex);
> #endif
> + }
>
> return (ret);
> }
>
> static void

>
> ---------------------------(end of broadcast)---------------------------
> TIP 3: if posting/reading through Usenet, please send an appropriate
> subscribe-nomail command to majordomo(at)postgresql(dot)org so that your
> message can get through to the mailing list cleanly

--
Bruce Momjian | http://candle.pha.pa.us
pgman(at)candle(dot)pha(dot)pa(dot)us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Josh Berkus 2004-03-15 18:52:15 Re: listening addresses
Previous Message Bruce Momjian 2004-03-15 16:25:00 Re: Log rotation

Browse pgsql-patches by date

  From Date Subject
Next Message Josh Berkus 2004-03-15 18:52:15 Re: listening addresses
Previous Message Lee Kindness 2004-03-15 16:19:53 Re: ECPG - Remove need for "AT connection" when using threads