diff options
Diffstat (limited to 'src/interfaces/ecpg/test/thread/thread.pgc')
-rw-r--r-- | src/interfaces/ecpg/test/thread/thread.pgc | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/src/interfaces/ecpg/test/thread/thread.pgc b/src/interfaces/ecpg/test/thread/thread.pgc new file mode 100644 index 0000000..e7d8c00 --- /dev/null +++ b/src/interfaces/ecpg/test/thread/thread.pgc @@ -0,0 +1,136 @@ +/* + * Thread test program + * by Philip Yarra & Lee Kindness. + */ +#include <stdint.h> +#include <stdlib.h> +#include "ecpg_config.h" + +#ifndef ENABLE_THREAD_SAFETY +int +main(void) +{ + printf("No threading enabled.\n"); + return 0; +} +#else +#ifndef WIN32 +#include <pthread.h> +#else +#include <windows.h> +#include <locale.h> +#endif + +exec sql include ../regression; + +void *test_thread(void *arg); + +int nthreads = 10; +int iterations = 20; + +int main() +{ +#ifndef WIN32 + pthread_t *threads; +#else + HANDLE *threads; +#endif + intptr_t n; + EXEC SQL BEGIN DECLARE SECTION; + int l_rows; + EXEC SQL END DECLARE SECTION; + + /* Do not switch on debug output for regression tests. The threads get executed in + * more or less random order */ + /* ECPGdebug(1, stderr); */ + + /* setup test_thread table */ + EXEC SQL CONNECT TO REGRESSDB1; + 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(threads[0])); + if( threads == NULL ) + { + fprintf(stderr, "Cannot alloc memory\n"); + return 1; + } + for( n = 0; n < nthreads; n++ ) + { +#ifndef WIN32 + pthread_create(&threads[n], NULL, test_thread, (void *) (n + 1)); +#else + threads[n] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) (void (*) (void)) test_thread, (void *) (n + 1), 0, NULL); +#endif + } + + /* wait for thread completion */ +#ifndef WIN32 + for( n = 0; n < nthreads; n++ ) + { + pthread_join(threads[n], NULL); + } +#else + WaitForMultipleObjects(nthreads, threads, TRUE, INFINITE); +#endif + free(threads); + + /* and check results */ + EXEC SQL CONNECT TO REGRESSDB1; + EXEC SQL SELECT COUNT(*) INTO :l_rows FROM test_thread; + EXEC SQL COMMIT; + EXEC SQL DISCONNECT; + if( l_rows == (nthreads * iterations) ) + printf("Success.\n"); + else + printf("ERROR: Failure - expecting %d rows, got %d.\n", nthreads * iterations, l_rows); + + return 0; +} + +void *test_thread(void *arg) +{ + long threadnum = (intptr_t) 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 */ +#ifndef _MSC_VER + snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum); +#else + _snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum); +#endif + EXEC SQL WHENEVER sqlerror sqlprint; + EXEC SQL CONNECT TO REGRESSDB1 AS :l_connection; + if( sqlca.sqlcode != 0 ) + { + printf("%s: ERROR: cannot connect to database!\n", l_connection); + return NULL; + } + EXEC SQL AT :l_connection BEGIN; + + /* insert into test_thread table */ + for( l_i = 1; l_i <= iterations; l_i++ ) + { + EXEC SQL AT :l_connection INSERT INTO test_thread(thread, iteration) VALUES(:l_connection, :l_i); + if( sqlca.sqlcode != 0 ) + printf("%s: ERROR: insert failed!\n", l_connection); + } + + /* all done */ + EXEC SQL AT :l_connection COMMIT; + EXEC SQL DISCONNECT :l_connection; + return NULL; +} +#endif /* ENABLE_THREAD_SAFETY */ |