It appears as though os_unix.c references pthread routines directly
when SQLITE_THREADSAFE is defined (and not 0).

I think those routines should probably be abstracted like the mutex
routines.  The problem lies if an alternate threading implementation
is preferred on a unix-like system  (as is the case in some embedded
environments), or if the system doesn't support pthreads at all, but
an alternate threading implementation exists (ex. SCO OpenServer 5.0.6) and
you still want to maintain thread-safety.  Currently the only alternative
is to reimplement the entire VFS for Unix when all that is really
desired is to switch out the thread routines.

I've attached a patch for discussion which creates 4 new functions:
sqlite3_thread_create, sqlite3_thread_join, sqlite3_thread_self,
and sqlite3_thread_equal

Their use is roughly equivalent to the pthread_* counterparts.  The
main exception here is that I've expanded the API slightly because
Win32 differentiates between a thread id and a thread handle.
I've included a Win32 example implementation as well, even though
it is not used. 'make test' on Linux appears to return the same results
with this patch as it does without it.

Am I going about resolving this issue wrong? Any other thoughts
on this?

Thanks.
-Brad

diff -ruN sqlite-3.5.5.orig/src/mutex_unix.c sqlite-3.5.5/src/mutex_unix.c
--- sqlite-3.5.5.orig/src/mutex_unix.c  2008-01-22 21:13:56.000000000 -0500
+++ sqlite-3.5.5/src/mutex_unix.c       2008-02-05 17:45:25.000000000 -0500
@@ -295,4 +295,27 @@
   return p==0 || p->nRef==0 || pthread_equal(p->owner, pthread_self())==0;
 }
 #endif
+
+int sqlite3_thread_create(sqlite3_threadhandle_t *threadhandle, 
sqlite3_threadid_t *threadid, void *(*start_routine)(void *), void *arg){
+       if (pthread_create((pthread_t *)threadhandle, NULL, start_routine, arg) 
!= 0)
+               return(SQLITE_ERROR);
+       if (threadid)
+               *threadid = *threadhandle;
+       return(SQLITE_OK);
+}
+
+int sqlite3_thread_join(sqlite3_threadhandle_t threadhandle, void **value_ptr){
+       if (pthread_join((pthread_t)threadhandle, value_ptr) != 0)
+               return(SQLITE_ERROR);
+       return(SQLITE_OK);
+}
+
+sqlite3_threadid_t *sqlite3_thread_self(){
+       return((sqlite3_threadid_t)pthread_self());
+}
+
+int sqlite3_thread_equal(sqlite3_threadid_t t1, sqlite3_threadid_t t2){
+       return(pthread_equal((pthread_t)t1, (pthread_t)t2));
+}
+
 #endif /* SQLITE_MUTEX_PTHREAD */
diff -ruN sqlite-3.5.5.orig/src/mutex_w32.c sqlite-3.5.5/src/mutex_w32.c
--- sqlite-3.5.5.orig/src/mutex_w32.c   2008-01-22 21:13:56.000000000 -0500
+++ sqlite-3.5.5/src/mutex_w32.c        2008-02-05 17:45:30.000000000 -0500
@@ -216,4 +216,28 @@
 int sqlite3_mutex_notheld(sqlite3_mutex *p){
   return p==0 || p->nRef==0 || p->owner!=GetCurrentThreadId();
 }
+
+
+int sqlite3_thread_create(sqlite3_threadhandle_t *threadhandle, 
sqlite3_threadid_t *threadid, void *(*start_routine)(void *), void *arg){
+       *threadhandle = CreateThread(NULL, 0, 
(LPTHREAD_START_ROUTINE)start_routine, arg, 0, threadid);
+       if (*threadhandle == NULL)
+               return(SQLITE_ERROR);
+       return(SQLITE_OK);
+}
+
+int sqlite3_thread_join(sqlite3_threadhandle_t threadhandle, void **value_ptr){
+       if (WaitForSingleObject((HANDLE)threadhandle, INFINITE) != 
WAIT_OBJECT_O)
+               return(SQLITE_ERROR);
+       GetExitCodeThread((HANDLE)threadhandle, (LPDWORD)value_ptr);
+       return(SQLITE_OK);
+}
+
+sqlite3_threadid_t *sqlite3_thread_self(){
+       return((sqlite3_threadid_t)GetCurrentThreadId());
+}
+
+int sqlite3_thread_equal(sqlite3_threadid_t t1, sqlite3_threadid_t t2){
+       return(t1 == t2);
+}
+
 #endif /* SQLITE_MUTEX_W32 */
diff -ruN sqlite-3.5.5.orig/src/os_unix.c sqlite-3.5.5/src/os_unix.c
--- sqlite-3.5.5.orig/src/os_unix.c     2008-01-22 21:13:56.000000000 -0500
+++ sqlite-3.5.5/src/os_unix.c  2008-02-05 17:45:20.000000000 -0500
@@ -55,15 +55,6 @@
 #endif /* SQLITE_ENABLE_LOCKING_STYLE */
 
 /*
-** If we are to be thread-safe, include the pthreads header and define
-** the SQLITE_UNIX_THREADS macro.
-*/
-#if SQLITE_THREADSAFE
-# include <pthread.h>
-# define SQLITE_UNIX_THREADS 1
-#endif
-
-/*
 ** Default permissions when creating a new file
 */
 #ifndef SQLITE_DEFAULT_FILE_PERMISSIONS
@@ -98,7 +89,7 @@
   unsigned char locktype;   /* The type of lock held on this fd */
   int dirfd;                /* File descriptor for the directory */
 #if SQLITE_THREADSAFE
-  pthread_t tid;            /* The thread that "owns" this unixFile */
+  sqlite3_threadid_t tid;            /* The thread that "owns" this unixFile */
 #endif
 };
 
@@ -139,7 +130,7 @@
 ** testing and debugging only.
 */
 #if SQLITE_THREADSAFE
-#define threadid pthread_self()
+#define threadid sqlite3_thread_self()
 #else
 #define threadid 0
 #endif
@@ -161,9 +152,9 @@
 ** transferOwnership() function below for additional information
 */
 #if SQLITE_THREADSAFE
-# define SET_THREADID(X)   (X)->tid = pthread_self()
+# define SET_THREADID(X)   (X)->tid = sqlite3_thread_self()
 # define CHECK_THREADID(X) (threadsOverrideEachOthersLocks==0 && \
-                            !pthread_equal((X)->tid, pthread_self()))
+                            !sqlite3_thread_equal((X)->tid, 
sqlite3_thread_self()))
 #else
 # define SET_THREADID(X)
 # define CHECK_THREADID(X) 0
@@ -282,7 +273,7 @@
   dev_t dev;       /* Device number */
   ino_t ino;       /* Inode number */
 #if SQLITE_THREADSAFE
-  pthread_t tid;   /* Thread ID or zero if threads can override each other */
+  sqlite3_threadid_t tid;   /* Thread ID or zero if threads can override each 
other */
 #endif
 };
 
@@ -489,7 +480,7 @@
 static void testThreadLockingBehavior(int fd_orig){
   int fd;
   struct threadTestData d[2];
-  pthread_t t[2];
+  sqlite3_threadhandle_t t[2];
 
   fd = dup(fd_orig);
   if( fd<0 ) return;
@@ -501,10 +492,10 @@
   d[0].lock.l_whence = SEEK_SET;
   d[1] = d[0];
   d[1].lock.l_type = F_WRLCK;
-  pthread_create(&t[0], 0, threadLockingTest, &d[0]);
-  pthread_create(&t[1], 0, threadLockingTest, &d[1]);
-  pthread_join(t[0], 0);
-  pthread_join(t[1], 0);
+  sqlite3_thread_create(&t[0], NULL, threadLockingTest, &d[0]);
+  sqlite3_thread_create(&t[1], NULL, threadLockingTest, &d[1]);
+  sqlite3_thread_join(t[0], 0);
+  sqlite3_thread_join(t[1], 0);
   close(fd);
   threadsOverrideEachOthersLocks =  d[0].result==0 && d[1].result==0;
 }
@@ -640,7 +631,7 @@
   if( threadsOverrideEachOthersLocks<0 ){
     testThreadLockingBehavior(fd);
   }
-  key1.tid = threadsOverrideEachOthersLocks ? 0 : pthread_self();
+  key1.tid = threadsOverrideEachOthersLocks ? 0 : sqlite3_thread_self();
 #endif
   memset(&key2, 0, sizeof(key2));
   key2.dev = statbuf.st_dev;
@@ -735,13 +726,13 @@
 #if SQLITE_THREADSAFE
 static int transferOwnership(unixFile *pFile){
   int rc;
-  pthread_t hSelf;
+  sqlite3_threadid_t hSelf;
   if( threadsOverrideEachOthersLocks ){
     /* Ownership transfers not needed on this system */
     return SQLITE_OK;
   }
-  hSelf = pthread_self();
-  if( pthread_equal(pFile->tid, hSelf) ){
+  hSelf = sqlite3_thread_self();
+  if( sqlite3_thread_equal(pFile->tid, hSelf) ){
     /* We are still in the same thread */
     OSTRACE1("No-transfer, same thread\n");
     return SQLITE_OK;
diff -ruN sqlite-3.5.5.orig/src/sqlite.h.in sqlite-3.5.5/src/sqlite.h.in
--- sqlite-3.5.5.orig/src/sqlite.h.in   2008-01-31 11:36:40.000000000 -0500
+++ sqlite-3.5.5/src/sqlite.h.in        2008-02-05 17:45:03.000000000 -0500
@@ -671,6 +671,9 @@
 */
 typedef struct sqlite3_mutex sqlite3_mutex;
 
+typedef void * sqlite3_threadhandle_t;
+typedef void * sqlite3_threadid_t;
+
 /*
 ** CAPI3REF: OS Interface Object {F11140}
 **
@@ -4674,6 +4677,12 @@
 int sqlite3_mutex_try(sqlite3_mutex*);
 void sqlite3_mutex_leave(sqlite3_mutex*);
 
+int sqlite3_thread_create(sqlite3_threadhandle_t *threadhandle, 
sqlite3_threadid_t *threadid, void *(*start_routine)(void *), void *arg);
+int sqlite3_thread_join(sqlite3_threadhandle_t thread, void **value_ptr);
+sqlite3_threadid_t *sqlite3_thread_self();
+int sqlite3_thread_equal(sqlite3_threadid_t t1, sqlite3_threadid_t t2);
+
+
 /*
 ** CAPI3REF: Mutex Verifcation Routines {F17080}
 **
_______________________________________________
sqlite-users mailing list
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to