Add multithreading on Solaris and Linux by Janet Borschowa
authorHiroshi Inoue <inoue@tpf.co.jp>
Thu, 24 Oct 2002 09:51:07 +0000 (09:51 +0000)
committerHiroshi Inoue <inoue@tpf.co.jp>
Thu, 24 Oct 2002 09:51:07 +0000 (09:51 +0000)
 <borschow@roguewave.com>.

13 files changed:
connection.h
environ.c
environ.h
misc.c
misc.h
odbcapi30.c
pgapi30.c
psqlodbc.c
results.c
socket.c
statement.h
win32.mak
win32_30.mak

index 9993da47f4f57c10a5759d069060ae403be72452..c605e9c07262667d381a86aa8364e86da258b5bf 100644 (file)
@@ -15,6 +15,9 @@
 #include <string.h>
 #include "descriptor.h"
 
+#if defined (POSIX_MULTITHREAD_SUPPORT)
+#include <pthread.h>
+#endif
 
 typedef enum
 {
@@ -84,11 +87,16 @@ typedef enum
 #define CC_set_errornumber(x, n)   (x->__error_number = n)
 
 /* For Multi-thread */
-#ifdef WIN_MULTITHREAD_SUPPORT
+#if defined(WIN_MULTITHREAD_SUPPORT)
 #define INIT_CONN_CS(x)        InitializeCriticalSection(&((x)->cs))
 #define ENTER_CONN_CS(x)   EnterCriticalSection(&((x)->cs))
 #define LEAVE_CONN_CS(x)   LeaveCriticalSection(&((x)->cs))
 #define DELETE_CONN_CS(x)  DeleteCriticalSection(&((x)->cs))
+#elif defined(POSIX_MULTITHREAD_SUPPORT)
+#define INIT_CONN_CS(x)        pthread_mutex_init(&((x)->cs),0)
+#define ENTER_CONN_CS(x)   pthread_mutex_lock(&((x)->cs))
+#define LEAVE_CONN_CS(x)   pthread_mutex_unlock(&((x)->cs))
+#define DELETE_CONN_CS(x)  pthread_mutex_destroy(&((x)->cs))
 #else
 #define INIT_CONN_CS(x)    
 #define ENTER_CONN_CS(x)
@@ -321,8 +329,10 @@ struct ConnectionClass_
    int     be_key; /* auth code needed to send cancel */
    UInt4       isolation;
    char        *current_schema;
-#ifdef WIN_MULTITHREAD_SUPPORT
+#if defined(WIN_MULTITHREAD_SUPPORT)
    CRITICAL_SECTION    cs;
+#elif defined(POSIX_MULTITHREAD_SUPPORT)
+    pthread_mutex_t     cs;
 #endif /* WIN_MULTITHREAD_SUPPORT */
 };
 
index 9889c9064b09ad005dcd0f9ddea0208c95af17be..2db3bf0d674ab38b187c43157c7f5f4d6e316f9f 100644 (file)
--- a/environ.c
+++ b/environ.c
@@ -26,8 +26,10 @@ extern GLOBAL_VALUES globals;
 
 /* The one instance of the handles */
 ConnectionClass *conns[MAX_CONNECTIONS];
-#ifdef WIN_MULTITHREAD_SUPPORT
+#if defined(WIN_MULTITHREAD_SUPPORT)
 CRITICAL_SECTION   conns_cs;
+#elif defined(POSIX_MULTITHREAD_SUPPORT)
+pthread_mutex_t     conns_cs;
 #endif /* WIN_MULTITHREAD_SUPPORT */
 
 
index b2e0e38124f242fa44711cf7f13a019f19893fd0..8926eb116ec7e3727d9b9e51ed5cf19ed05aa486 100644 (file)
--- a/environ.h
+++ b/environ.h
@@ -19,8 +19,10 @@ struct EnvironmentClass_
    char       *errormsg;
    int     errornumber;
    Int4    flag;
-#ifdef WIN_MULTITHREAD_SUPPORT
+#if defined(WIN_MULTITHREAD_SUPPORT)
    CRITICAL_SECTION    cs;
+#elif defined(POSIX_MULTITHREAD_SUPPORT)
+    pthread_mutex_t     cs;
 #endif /* WIN_MULTITHREAD_SUPPORT */
 };
 
@@ -43,7 +45,7 @@ void      EN_log_error(char *func, char *desc, EnvironmentClass *self);
 #define    EN_unset_pooling(env) (env->flag &= ~EN_CONN_POOLING)
 
 /* For Multi-thread */
-#ifdef  WIN_MULTITHREAD_SUPPORT
+#if defined( WIN_MULTITHREAD_SUPPORT)
 #define    INIT_CONNS_CS   InitializeCriticalSection(&conns_cs)
 #define    ENTER_CONNS_CS  EnterCriticalSection(&conns_cs)
 #define    LEAVE_CONNS_CS  LeaveCriticalSection(&conns_cs)
@@ -52,6 +54,15 @@ void     EN_log_error(char *func, char *desc, EnvironmentClass *self);
 #define ENTER_ENV_CS(x)        EnterCriticalSection(&((x)->cs))
 #define LEAVE_ENV_CS(x)        LeaveCriticalSection(&((x)->cs))
 #define DELETE_ENV_CS(x)   DeleteCriticalSection(&((x)->cs))
+#elif defined(POSIX_MULTITHREAD_SUPPORT)
+#define    INIT_CONNS_CS   pthread_mutex_init(&conns_cs,0)
+#define    ENTER_CONNS_CS  pthread_mutex_lock(&conns_cs)
+#define    LEAVE_CONNS_CS  pthread_mutex_unlock(&conns_cs)
+#define    DELETE_CONNS_CS pthread_mutex_destroy(&conns_cs)
+#define INIT_ENV_CS(x)     pthread_mutex_init(&((x)->cs),0)
+#define ENTER_ENV_CS(x)        pthread_mutex_lock(&((x)->cs))
+#define LEAVE_ENV_CS(x)        pthread_mutex_unlock(&((x)->cs))
+#define DELETE_ENV_CS(x)   pthread_mutex_destroy(&((x)->cs))
 #else
 #define    INIT_CONNS_CS
 #define    ENTER_CONNS_CS
diff --git a/misc.c b/misc.c
index 05f8eaeb4798eb7089c7356f7236e80067862d41..7fc591e259decbfb9f1ecbf6ae6c40878b5780a5 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -57,8 +57,10 @@ generate_filename(const char *dirname, const char *prefix, char *filename)
    return;
 }
 
-#ifdef WIN_MULTITHREAD_SUPPORT
+#if defined(WIN_MULTITHREAD_SUPPORT)
 CRITICAL_SECTION   qlog_cs, mylog_cs;
+#elif defined(POSIX_MULTITHREAD_SUPPORT)
+pthread_mutex_t    qlog_cs, mylog_cs;
 #endif /* WIN_MULTITHREAD_SUPPORT */
 static int mylog_on = 0,
            qlog_on = 0;
@@ -122,6 +124,10 @@ mylog(char *fmt,...)
            fprintf(LOGFP, "[%d]", GetCurrentThreadId());
 #endif /* WIN32 */
 #endif /* WIN_MULTITHREAD_SUPPORT */
+#if defined(POSIX_MULTITHREAD_SUPPORT)
+        if (LOGFP)
+            fprintf(LOGFP, "[%d]", pthread_self());
+#endif /* POSIX_MULTITHREAD_SUPPORT */
        if (LOGFP)
            vfprintf(LOGFP, fmt, args);
 
diff --git a/misc.h b/misc.h
index e55b91ad07b8cdf5471900542a8675295ed78155..b0a663b6c298684a40922e880ec522d25ee0b5ea 100644 (file)
--- a/misc.h
+++ b/misc.h
@@ -29,7 +29,7 @@
 */
 #define Q_LOG
 
-#ifdef WIN_MULTITHREAD_SUPPORT
+#if defined(WIN_MULTITHREAD_SUPPORT)
 #define    INIT_QLOG_CS    InitializeCriticalSection(&qlog_cs)
 #define    ENTER_QLOG_CS   EnterCriticalSection(&qlog_cs)
 #define    LEAVE_QLOG_CS   LeaveCriticalSection(&qlog_cs)
 #define    ENTER_MYLOG_CS  EnterCriticalSection(&mylog_cs)
 #define    LEAVE_MYLOG_CS  LeaveCriticalSection(&mylog_cs)
 #define    DELETE_MYLOG_CS DeleteCriticalSection(&mylog_cs)
+#elif defined(POSIX_MULTITHREAD_SUPPORT)
+#define    INIT_QLOG_CS    pthread_mutex_init(&qlog_cs,0)
+#define    ENTER_QLOG_CS   pthread_mutex_lock(&qlog_cs)
+#define    LEAVE_QLOG_CS   pthread_mutex_unlock(&qlog_cs)
+#define    DELETE_QLOG_CS  pthread_mutex_destroy(&qlog_cs)
+#define    INIT_MYLOG_CS   pthread_mutex_init(&mylog_cs,0)
+#define    ENTER_MYLOG_CS  pthread_mutex_lock(&mylog_cs)
+#define    LEAVE_MYLOG_CS  pthread_mutex_unlock(&mylog_cs)
+#define    DELETE_MYLOG_CS pthread_mutex_destroy(&mylog_cs)
 #else
 #define    INIT_QLOG_CS
 #define    ENTER_QLOG_CS
index 6cd70ced10c937475de4f7b8b923371b6b056b90..bf3952d0425e2dc2c7d967f57780205bbe469314 100644 (file)
@@ -442,7 +442,7 @@ SQLSetEnvAttr(HENV EnvironmentHandle,
                    EN_unset_pooling(env);
                    ret = SQL_SUCCESS;
                    break;
-#ifdef WIN_MULTITHREAD_SUPPORT
+#if defined(WIN_MULTITHREAD_SUPPORT) || defined(POSIX_MULTITHREAD_SUPPORT)
                case SQL_CP_ONE_PER_DRIVER:
                    EN_set_pooling(env);
                    ret = SQL_SUCCESS;
index 24552a81fc11c59d9ed772ea0e3551dc5d61ea43..4c0b40f89779fdf5bcdc06e02ab48bcfce005627 100644 (file)
--- a/pgapi30.c
+++ b/pgapi30.c
@@ -1404,7 +1404,8 @@ PGAPI_SetConnectAttr(HDBC ConnectionHandle,
        case SQL_ATTR_CONNECTION_DEAD:
        case SQL_ATTR_CONNECTION_TIMEOUT:
        case SQL_ATTR_METADATA_ID:
-           CC_set_error(conn, STMT_INVALID_OPTION_IDENTIFIER, "Unsupported connect attribute (Set)");
+       case SQL_ATTR_ENLIST_IN_DTC:
+           CC_set_error(conn, STMT_OPTION_NOT_FOR_THE_DRIVER, "Unsupported connect attribute (Set)");
            return SQL_ERROR;
        default:
            ret = PGAPI_SetConnectOption(ConnectionHandle, (UWORD) Attribute, (UDWORD) Value);
index 86d9a80e5142d93fb72a24dcb01155ed3b7c4eaf..fba807cf09d249278237847fdc8bddc9ae08d1e8 100644 (file)
@@ -27,8 +27,10 @@ RETCODE SQL_API SQLDummyOrdinal(void);
 
 #ifdef WIN32
 HINSTANCE NEAR s_hModule;      /* Saved module handle. */
-#ifdef WIN_MULTITHREAD_SUPPORT
+#if defined(WIN_MULTITHREAD_SUPPORT)
 extern CRITICAL_SECTION    qlog_cs, mylog_cs, conns_cs;
+#elif defined(POSIX_MULTITHREAD_SUPPORT)
+extern pthread_mutex_t     qlog_cs, mylog_cs, conns_cs;
 #endif /* WIN_MULTITHREAD_SUPPORT */
 
 /* This is where the Driver Manager attaches to this Driver */
@@ -68,8 +70,8 @@ DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
 
        case DLL_PROCESS_DETACH:
            DELETE_CONNS_CS;
+            DELETE_MYLOG_CS;
            DELETE_QLOG_CS;
-           DELETE_MYLOG_CS;
            WSACleanup();
            return TRUE;
 
index 7f056cc23b66aab5152e9c47fa2b65d4ce666df1..b8256dc426de10b8b373637899351ebb72033f4a 100644 (file)
--- a/results.c
+++ b/results.c
@@ -1012,7 +1012,7 @@ PGAPI_Fetch(
            return SQL_NO_DATA_FOUND;
        /* just to avoid a crash if the user insists on calling this */
        /* function even if SQL_ExecDirect has reported an Error */
-       SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Bindings were not allocated properly.");
+       SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Bindings were not allocated properly.");
        SC_log_error(func, "", stmt);
        return SQL_ERROR;
    }
@@ -1193,7 +1193,7 @@ PGAPI_ExtendedFetch(
            return SQL_NO_DATA_FOUND;
        /* just to avoid a crash if the user insists on calling this */
        /* function even if SQL_ExecDirect has reported an Error */
-       SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Bindings were not allocated properly.");
+       SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Bindings were not allocated properly.");
        SC_log_error(func, "", stmt);
        return SQL_ERROR;
    }
index 7f5635927470205c7c07bba5c7c1c13c5604ae63..38541a35d464d2f93e32b1aa52564c743b98787f 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -106,7 +106,15 @@ SOCK_Destructor(SocketClass *self)
 char
 SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname)
 {
-   struct hostent *host;
+#if defined (POSIX_MULTITHREAD_SUPPORT)
+    const int bufsz = 8192; 
+    char buf[bufsz];
+    int error = 0;
+    struct hostent host;
+    struct hostent* hp = &host;
+#else
+    struct hostent* hp;
+#endif 
    unsigned long iaddr;
 
    if (self->socket != -1)
@@ -124,14 +132,25 @@ SOCK_connect_to(SocketClass *self, unsigned short port, char *hostname)
    iaddr = inet_addr(hostname);
    if (iaddr == INADDR_NONE)
    {
-       host = gethostbyname(hostname);
-       if (host == NULL)
+#if defined (POSIX_MULTITHREAD_SUPPORT) 
+  #if defined (PGS_REENTRANT_API_1) // solaris, irix
+        hp = gethostbyname_r(hostname, hp, buf, bufsz, &error);
+  #elif defined (PGS_REENTRANT_API_2) // linux
+        int result = 0;
+        result = gethostbyname_r(hostname, hp, buf, bufsz, &hp, &error);
+        if (result)
+          hp = 0;
+  #endif
+#else
+        hp = gethostbyname(hostname);
+#endif
+       if (hp == NULL)
        {
            self->errornumber = SOCKET_HOST_NOT_FOUND;
            self->errormsg = "Could not resolve hostname.";
            return 0;
        }
-       memcpy(&(self->sadr.sin_addr), host->h_addr, host->h_length);
+       memcpy(&(self->sadr.sin_addr), hp->h_addr, hp->h_length);
    }
    else
        memcpy(&(self->sadr.sin_addr), (struct in_addr *) & iaddr, sizeof(iaddr));
index 7b17250f1c5ba6f410989d9ab2541ef7d57fafdc..52dbf0d9cb84dfd1b930ee410ee7074127f5e1f5 100644 (file)
@@ -14,6 +14,9 @@
 #include "bind.h"
 #include "descriptor.h"
 
+#if defined (POSIX_MULTITHREAD_SUPPORT)
+#include <pthread.h>
+#endif
 
 #ifndef FALSE
 #define FALSE  (BOOL)0
@@ -143,7 +146,7 @@ struct StatementClass_
                                 * SetPos, SQLFetch) */
    int         save_rowset_size;       /* saved rowset size in case of
                                         * change/FETCH_NEXT */
-   int         rowset_start;   /* start of rowset (an absolute row
+   Int4            rowset_start;   /* start of rowset (an absolute row
                                 * number) */
    int         bind_row;       /* current offset for Multiple row/column
                                 * binding */
@@ -198,8 +201,10 @@ struct StatementClass_
    Int4        from_pos;   
    Int4        where_pos;
    Int4        last_fetch_count_include_ommitted;
-#ifdef WIN_MULTITHREAD_SUPPORT
+#if defined(WIN_MULTITHREAD_SUPPORT)
    CRITICAL_SECTION    cs;
+#elif defined(POSIX_MULTITHREAD_SUPPORT)
+    pthread_mutex_t     cs;
 #endif /* WIN_MULTITHREAD_SUPPORT */
 
 };
@@ -231,11 +236,16 @@ struct StatementClass_
 #define SC_is_fetchcursor(a)   ((a->miscinfo & 2L) != 0)
 
 /* For Multi-thread */
-#ifdef WIN_MULTITHREAD_SUPPORT
+#if defined(WIN_MULTITHREAD_SUPPORT)
 #define INIT_STMT_CS(x)        InitializeCriticalSection(&((x)->cs))
 #define ENTER_STMT_CS(x)   EnterCriticalSection(&((x)->cs))
 #define LEAVE_STMT_CS(x)   LeaveCriticalSection(&((x)->cs))
 #define DELETE_STMT_CS(x)  DeleteCriticalSection(&((x)->cs))
+#elif defined(POSIX_MULTITHREAD_SUPPORT)
+#define INIT_STMT_CS(x)        pthread_mutex_init(&((x)->cs),0)
+#define ENTER_STMT_CS(x)   pthread_mutex_lock(&((x)->cs))
+#define LEAVE_STMT_CS(x)   pthread_mutex_unlock(&((x)->cs))
+#define DELETE_STMT_CS(x)  pthread_mutex_destroy(&((x)->cs))
 #else
 #define INIT_STMT_CS(x)
 #define ENTER_STMT_CS(x)
index af801a9544850f6fafe04a8fcad3c717e6e1b633..5390948a7a79cac9ab5f4623bebb56034d74a74d 100644 (file)
--- a/win32.mak
+++ b/win32.mak
@@ -295,7 +295,7 @@ LINK32_OBJS= \
    "$(INTDIR)\execute.obj" \
    "$(INTDIR)\info.obj" \
    "$(INTDIR)\lobj.obj" \
-   "$(INTDIR)\win_md5.obj"
+   "$(INTDIR)\win_md5.obj" \
    "$(INTDIR)\misc.obj" \
 !IF "$(CFG)" == "MultibyteDebug" 
    "$(INTDIR)\multibyte.obj" \
index 1c25b3406b3b0a6bd2ae8bfaf7022df3a71abd34..7dba5e06a817a0f4e8fcf3442d1538ec2e5a5077 100755 (executable)
@@ -304,7 +304,7 @@ LINK32_OBJS= \
    "$(INTDIR)\info.obj" \
    "$(INTDIR)\info30.obj" \
    "$(INTDIR)\lobj.obj" \
-   "$(INTDIR)\win_md5.obj"
+   "$(INTDIR)\win_md5.obj" \
    "$(INTDIR)\misc.obj" \
 !IF "$(CFG)" == "MultibyteDebug30" 
    "$(INTDIR)\multibyte.obj" \