/* * Thread test program * by Lee Kindness. */ #include #include #include "ecpg_config.h" #ifndef ENABLE_THREAD_SAFETY int main(void) { printf("No threading enabled.\n"); return 0; } #else #ifndef WIN32 #include #else #include #include #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 BEGIN; /* insert into test_thread table */ for( l_i = 1; l_i <= iterations; l_i++ ) { EXEC SQL 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 COMMIT; EXEC SQL DISCONNECT :l_connection; return NULL; } #endif /* ENABLE_THREAD_SAFETY */