Index: trunk/psLib/src/db/psDB.c
===================================================================
--- trunk/psLib/src/db/psDB.c	(revision 7617)
+++ trunk/psLib/src/db/psDB.c	(revision 7626)
@@ -12,6 +12,6 @@
  *  @author Joshua Hoblitt
  *
- *  @version $Revision: 1.59 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-06-21 21:40:12 $
+ *  @version $Revision: 1.60 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-06-22 00:36:22 $
  *
  *  Copyright 2005 Joshua Hoblitt, University of Hawaii
@@ -37,4 +37,13 @@
 #include "psErrorText.h"
 
+// set the pointer to NULL if we are actually freeing the memory
+#define PSDB_NULL_FREE(ptr) \
+if (psMemGetRefCounter(ptr) == 1) { \
+    psFree(ptr); \
+    ptr = NULL; \
+} else { \
+    psFree(ptr); \
+}
+
 typedef struct
 {
@@ -44,5 +53,5 @@
 mysqlType;
 
-//static pthread_mutex_t lookupTableMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t lookupTableMutex = PTHREAD_MUTEX_INITIALIZER;
 static psHash   *pTypeToSQLlookupTable = NULL;
 static psHash   *sqlToPTypeLookupTable = NULL;
@@ -71,14 +80,18 @@
 static mysqlType *psDBPTypeToMySQL(psElemType pType);
 
-static psHash  *psDBGetPTypeToSQLTable(void);
+static psHash  *psDBPTypeToSQLTableSetup(void);
+static psHash  *psDBPTypeToSQLTableGet(void);
 static void     psDBPTypeToSQLTableCleanup(void);
 
-static psHash  *psDBGetSQLToPTypeTable(void);
+static psHash  *psDBSQLToPTypeTableSetup(void);
+static psHash  *psDBSQLToPTypeTableGet(void);
 static void     psDBSQLToPTypeTableCleanup(void);
 
-static psHash  *psDBGetMySQLToSQLTable(void);
+static psHash  *psDBMySQLToSQLTableSetup(void);
+static psHash  *psDBMySQLToSQLTableGet(void);
 static void     psDBMySQLToSQLTableCleanup(void);
 
-static psHash  *psDBGetPTypeToMySQLTable(void);
+static psHash  *psDBPTypeToMySQLTableSetup(void);
+static psHash  *psDBPTypeToMySQLTableGet(void);
 static void     psDBPTypeToMySQLTableCleanup(void);
 
@@ -136,4 +149,20 @@
     }
 
+    if (psMemGetThreadSafety()) {
+        pthread_mutex_lock(&lookupTableMutex);
+
+        psDBPTypeToSQLTableSetup();
+        psDBSQLToPTypeTableSetup();
+        psDBMySQLToSQLTableSetup();
+        psDBPTypeToMySQLTableSetup();
+
+        pthread_mutex_unlock(&lookupTableMutex);
+    } else {
+        psDBPTypeToSQLTableSetup();
+        psDBSQLToPTypeTableSetup();
+        psDBMySQLToSQLTableSetup();
+        psDBPTypeToMySQLTableSetup();
+    }
+
     return dbh;
 }
@@ -142,17 +171,30 @@
 {
     // Check if argument dbh is NULL
-    if(dbh == NULL) {
+    if(!dbh) {
         psError(PS_ERR_BAD_PARAMETER_TYPE, true,
                 PS_ERRORTEXT_psDB_INVALID_PSDB);
+        return;
+    }
+
+    // Attempt to close specified database connection
+    mysql_close(dbh->mysql);
+    psFree(dbh);
+
+    // ASC WARNING NOTE: the psDBSQLToPTypeTableCleanup cleanup routine
+    // needs to be called first because it refers to
+    // psDBPTypeToSQLTableGet ...
+    //
+    // The *cleanup functions should be thread safe as they just call psFree()
+    // but we don't want to be cleaning up & setting up at the same time
+    if (psMemGetThreadSafety()) {
+        pthread_mutex_lock(&lookupTableMutex);
+
+        psDBSQLToPTypeTableCleanup();
+        psDBMySQLToSQLTableCleanup();
+        psDBPTypeToSQLTableCleanup();
+        psDBPTypeToMySQLTableCleanup();
+
+        pthread_mutex_unlock(&lookupTableMutex);
     } else {
-
-        // Attempt to close specified database connection
-        mysql_close(dbh->mysql);
-        dbh->mysql = NULL;
-        psFree(dbh);
-
-        // ASC WARNING NOTE: the psDBSQLToPTypeTableCleanup cleanup routine
-        // needs to be called first because it refers to
-        // psDBGetPTypeToSQLTable ...
         psDBSQLToPTypeTableCleanup();
         psDBMySQLToSQLTableCleanup();
@@ -1548,5 +1590,5 @@
     psU32           pType;              // psElemType of a field
 
-    mysqlToSQLTable = psDBGetMySQLToSQLTable();
+    mysqlToSQLTable = psDBMySQLToSQLTableGet();
 
     // lookup MySQL column type
@@ -1554,5 +1596,4 @@
     sqlType = psHashLookup(mysqlToSQLTable, key);
     psFree(key);
-    psFree(mysqlToSQLTable);
 
     if (!sqlType) {
@@ -1572,7 +1613,6 @@
 
     // convert MySQL type to PS type
-    sqlToPSTable = psDBGetSQLToPTypeTable();
+    sqlToPSTable = psDBSQLToPTypeTableGet();
     value = psHashLookup(sqlToPSTable, sqlType);
-    psFree(sqlToPSTable);
 
     if (!value) {
@@ -1593,10 +1633,9 @@
     char            *sqlType;             // hash tmp value
 
-    pTypeToSQLTable = psDBGetPTypeToSQLTable();
+    pTypeToSQLTable = psDBPTypeToSQLTableGet();
 
     key = psDBIntToString((psU64)pType);
     sqlType = psHashLookup(pTypeToSQLTable, key);
     psFree(key);
-    psFree(pTypeToSQLTable);
 
     if (!sqlType) {
@@ -1617,10 +1656,9 @@
     mysqlType       *mType;             // mysqlType struct to return
 
-    pTypeToMySQLTable = psDBGetPTypeToMySQLTable();
+    pTypeToMySQLTable = psDBPTypeToMySQLTableGet();
 
     key = psDBIntToString((psU64)pType);
     mType = psHashLookup(pTypeToMySQLTable, key);
     psFree(key);
-    psFree(pTypeToMySQLTable);
 
     if (!mType) {
@@ -1635,7 +1673,8 @@
 }
 
-static psHash *psDBGetPTypeToSQLTable(void)
-{
-
+// PTypeToSQLTable
+
+static psHash *psDBPTypeToSQLTableSetup(void)
+{
     if (!pTypeToSQLlookupTable) {
         pTypeToSQLlookupTable = psHashAlloc(14);
@@ -1656,18 +1695,26 @@
         psDBAddToLookupTable(pTypeToSQLlookupTable, PS_TYPE_BOOL,"TINYINT");
         psDBAddToLookupTable(pTypeToSQLlookupTable, PS_DATA_STRING, "VARCHAR");
-    }
-
-    // simulate true ref counting
-    psMemIncrRefCounter(pTypeToSQLlookupTable);
+    } else {
+        // increment the ref count by one for every psDB
+        psMemIncrRefCounter(pTypeToSQLlookupTable);
+    }
 
     return pTypeToSQLlookupTable;
 }
 
+static psHash *psDBPTypeToSQLTableGet(void)
+{
+    return pTypeToSQLlookupTable;
+}
+
 static void psDBPTypeToSQLTableCleanup(void)
 {
-    psFree(pTypeToSQLlookupTable);
-}
-
-static psHash *psDBGetSQLToPTypeTable(void)
+    PSDB_NULL_FREE(pTypeToSQLlookupTable);
+}
+
+
+// SQLToPTypeTable
+
+static psHash *psDBSQLToPTypeTableSetup(void)
 {
     psHash          *psToSQLTable;
@@ -1679,5 +1726,5 @@
     if (!sqlToPTypeLookupTable) {
         // invert the PSToSQL table
-        psToSQLTable = psDBGetPTypeToSQLTable();
+        psToSQLTable = psDBPTypeToSQLTableGet();
         sqlToPTypeLookupTable = psHashAlloc(psToSQLTable->n);
 
@@ -1705,18 +1752,26 @@
         psFree(list);
         psFree(psToSQLTable);
-    }
-
-    // simulate true ref counting
-    psMemIncrRefCounter(sqlToPTypeLookupTable);
+    } else {
+        // increment the ref count by one for every psDB
+        psMemIncrRefCounter(sqlToPTypeLookupTable);
+    }
 
     return sqlToPTypeLookupTable;
 }
 
+static psHash *psDBSQLToPTypeTableGet(void)
+{
+    return sqlToPTypeLookupTable;
+}
+
 static void psDBSQLToPTypeTableCleanup(void)
 {
-    psFree(sqlToPTypeLookupTable);
-}
-
-static psHash *psDBGetMySQLToSQLTable(void)
+    PSDB_NULL_FREE(sqlToPTypeLookupTable);
+}
+
+
+// MySQLToSQLTable
+
+static psHash *psDBMySQLToSQLTableSetup(void)
 {
     if (!mysqlToSqlLookupTable) {
@@ -1743,18 +1798,26 @@
         psDBAddToLookupTable(mysqlToSqlLookupTable, FIELD_TYPE_NULL,      "NULL-type");
         psDBAddToLookupTable(mysqlToSqlLookupTable, FIELD_TYPE_CHAR,      "TINYINT");
-    }
-
-    // simulate true ref counting
-    psMemIncrRefCounter(mysqlToSqlLookupTable);
+    } else {
+        // increment the ref count by one for every psDB
+        psMemIncrRefCounter(mysqlToSqlLookupTable);
+    }
 
     return mysqlToSqlLookupTable;
 }
 
+static psHash *psDBMySQLToSQLTableGet(void)
+{
+    return mysqlToSqlLookupTable;
+}
+
 static void psDBMySQLToSQLTableCleanup(void)
 {
-    psFree(mysqlToSqlLookupTable);
-}
-
-static psHash *psDBGetPTypeToMySQLTable(void)
+    PSDB_NULL_FREE(mysqlToSqlLookupTable);
+}
+
+
+// PTypeToMySQLTable
+
+static psHash *psDBPTypeToMySQLTableSetup(void)
 {
     if (!pTypeToMysqlLookupTable) {
@@ -1789,15 +1852,20 @@
         //        psDBAddVoidToLookupTable(pTypeToMysqlLookupTable, PS_DATA_ASTROM, psDBMySQLTypeAlloc(MYSQL_TYPE_VAR_STRING, false));
         psDBAddVoidToLookupTable(pTypeToMysqlLookupTable, PS_DATA_UNKNOWN,psDBMySQLTypeAlloc(MYSQL_TYPE_VAR_STRING, false));
-    }
-
-    // simulate true ref counting
-    psMemIncrRefCounter(pTypeToMysqlLookupTable);
+    } else {
+        // increment the ref count by one for every psDB
+        psMemIncrRefCounter(pTypeToMysqlLookupTable);
+    }
 
     return pTypeToMysqlLookupTable;
 }
 
+static psHash *psDBPTypeToMySQLTableGet(void)
+{
+    return pTypeToMysqlLookupTable;
+}
+
 static void psDBPTypeToMySQLTableCleanup(void)
 {
-    psFree(pTypeToMysqlLookupTable);
+    PSDB_NULL_FREE(pTypeToMysqlLookupTable);
 }
 
