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

Поиск
Список
Период
Сортировка
От Bruce Momjian
Тема Re: ECPG - Remove need for "AT connection" when using threads
Дата
Msg-id 200403151627.i2FGRmV17825@candle.pha.pa.us
обсуждение исходный текст
Ответ на Re: ECPG - Remove need for "AT connection" when using threads  (Lee Kindness <lkindness@csl.co.uk>)
Список 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@postgresql.org so that your
>       message can get through to the mailing list cleanly

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

В списке pgsql-patches по дате отправления:

Предыдущее
От: Lee Kindness
Дата:
Сообщение: Re: ECPG - Remove need for "AT connection" when using threads
Следующее
От: Michael Meskes
Дата:
Сообщение: Re: ECPG - Remove need for "AT connection" when using threads