[freetds] 0.64 status and coverage

liam@inodes.org liam at inodes.org
Mon Jul 25 01:06:09 EDT 2005


On Fri, Jul 08, 2005 at 06:43:02PM +0200, Frediano Ziglio wrote:

> Feel free to send a patch. I agree to remove volatile and use
> syncronization function. unittests are mainly internal unit tests even

Please find the patch attached. I've slightly changed how the unit test
works as well as I feel this provides more appropriate coverage for a
multi-threaded unit test.

Cheers.
-------------- next part --------------
--- /tmp/freetds-0.64.dev.20050724/src/dblib/unittests/thread.c	2005-05-18 22:00:06.000000000 +1000
+++ thread.c	2005-07-25 15:02:49.000000000 +1000
@@ -20,7 +20,7 @@
 #include <sqldb.h>
 
 #ifdef TDS_HAVE_PTHREAD_MUTEX
-
+#include <pthread.h>
 #include <unistd.h>
 #include "tdsthread.h"
 
@@ -29,62 +29,39 @@
 static char software_version[] = "$Id: thread.c,v 1.3 2005/05/18 12:00:06 freddy77 Exp $";
 static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
 
-static TDS_MUTEX_DECLARE(mutex);
+pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 
-static LOGINREC *login = NULL;
-static volatile int result = 0;
-static volatile int thread_count = 0;
+int result = 0;
+int thread_count = 0;
+LOGINREC *login = NULL;
 
 #define ROWS 20
 #define NUM_THREAD 10
-#define NUM_LOOP 100
+#define NUM_LOOP 1000
 
 static void
 set_failed(void)
 {
-	TDS_MUTEX_LOCK(&mutex);
+	pthread_mutex_lock(&mutex);
 	result = 1;
-	TDS_MUTEX_UNLOCK(&mutex);
+	pthread_mutex_unlock(&mutex);
 }
 
 static int
-test(void)
+test(DBPROCESS *dbproc)
 {
-	DBPROCESS *dbproc;
 	int i;
 	char teststr[1024];
 	DBINT testint;
-	LOGINREC *login;
-
-	dbinit();
-
-	login = dblogin();
-	DBSETLPWD(login, PASSWORD);
-	DBSETLUSER(login, USER);
-	DBSETLAPP(login, "thread");
-
-	dbproc = dbopen(login, SERVER);
-	if (!dbproc) {
-		dbloginfree(login);
-		fprintf(stderr, "Unable to connect to %s\n", SERVER);
-		if (thread_count <= 5)
-			set_failed();
-		return 1;
-	}
-	dbloginfree(login);
 
-	if (strlen(DATABASE))
-		dbuse(dbproc, DATABASE);
 
 	/* fprintf(stdout, "select\n"); */
 	dbcmd(dbproc, "select * from dblib_thread order by i");
 	dbsqlexec(dbproc);
 
-
 	if (dbresults(dbproc) != SUCCEED) {
 		fprintf(stdout, "Was expecting a result set.\n");
 		set_failed();
-		dbclose(dbproc);
 		return 1;
 	}
 
@@ -108,7 +85,6 @@
 		if (REG_ROW != dbnextrow(dbproc)) {
 			fprintf(stderr, "Failed.  Expected a row\n");
 			set_failed();
-			dbclose(dbproc);
 			return 1;
 		}
 		if (testint != i) {
@@ -126,13 +102,10 @@
 	if (dbnextrow(dbproc) != NO_MORE_ROWS) {
 		fprintf(stderr, "Was expecting no more rows\n");
 		set_failed();
-		dbclose(dbproc);
 		return 1;
 	}
 
-	dbclose(dbproc);
-
-	dbexit();
+	dbcancel(dbproc);
 
 	return 0;
 }
@@ -142,17 +115,46 @@
 {
 	int i;
 	int num = (int) arg;
+	DBPROCESS *dbproc;
+	LOGINREC *login;
+
+	login = dblogin();
+	DBSETLPWD(login, PASSWORD);
+	DBSETLUSER(login, USER);
+	DBSETLAPP(login, "thread");
+
+	dbproc = dbopen(login, SERVER);
+	if (!dbproc) {
+		dbloginfree(login);
+		fprintf(stderr, "Unable to connect to %s\n", SERVER);
+		set_failed();
+		return NULL;
+	}
+	dbloginfree(login);
+
+	if (strlen(DATABASE))
+		dbuse(dbproc, DATABASE);
+
+	pthread_mutex_lock(&mutex);
+	++thread_count;
+	pthread_mutex_unlock(&mutex);
+
+	printf("thread %2d waiting for all threads to start\n", num+1);
+	pthread_mutex_lock(&mutex);
+	while (thread_count < NUM_THREAD) {
+		pthread_mutex_unlock(&mutex);
+		sleep(1);
+		pthread_mutex_lock(&mutex);
+	}
+	pthread_mutex_unlock(&mutex);
 
 	for (i = 1; i <= NUM_LOOP; ++i) {
-		printf("thread %2d of %2d loop %d\n", num, NUM_THREAD, i);
-		if (test() || result != 0)
+		printf("thread %2d of %2d loop %d\n", num+1, NUM_THREAD, i);
+		if (test(dbproc) || result != 0)
 			break;
 	}
 
-	TDS_MUTEX_LOCK(&mutex);
-	--thread_count;
-	TDS_MUTEX_UNLOCK(&mutex);
-
+	dbclose(dbproc);
 	return NULL;
 }
 
@@ -160,7 +162,7 @@
 main(int argc, char **argv)
 {
 	int i;
-	pthread_t th;
+	pthread_t th[NUM_THREAD];
 	DBPROCESS *dbproc;
 
 	read_login_info(argc, argv);
@@ -216,21 +218,19 @@
 		}
 	}
 
-	for (i = 1; i <= NUM_THREAD; ++i) {
-		TDS_MUTEX_LOCK(&mutex);
-		++thread_count;
-		TDS_MUTEX_UNLOCK(&mutex);
-		if (pthread_create(&th, NULL, thread_test, (void *) i) != 0) {
+	for (i = 0; i < NUM_THREAD; ++i) {
+		if (pthread_create(&th[i], NULL, thread_test, (void *) i) != 0)
+		{
 			fprintf(stderr, "Error creating thread\n");
 			return 1;
 		}
-		pthread_detach(th);
-		usleep(20000);
+		/* MSSQL rejects the connections if they come in too fast */
+		sleep(1);
 	}
 
-	for (i = 1; thread_count > 0; ++i) {
-		printf("loop %d thread count %d... waiting\n", i, thread_count);
-		sleep(2);
+	for (i = 0; i < NUM_THREAD; ++i) {
+		pthread_join(th[i], NULL);
+		fprintf(stdout, "thread: %d exited\n", i);
 	}
 
 	dbloginfree(login);
@@ -255,4 +255,3 @@
 	return 0;
 }
 #endif
-


More information about the FreeTDS mailing list