Now uses thread-specific persistent database connections for performance.
authorMatthew Mondor <mmondor@pulsar-zone.net>
Mon, 19 Mar 2007 09:00:10 +0000 (09:00 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Mon, 19 Mar 2007 09:00:10 +0000 (09:00 +0000)
Does not need the PostgreSQL client library to be compiled with
thread-safety option as each thread only accesses its own PGconn object.

mmsoftware/mmmail/src/mmpop3d/mmpop3d.c
mmsoftware/mmmail/src/mmpop3d/mmpop3d.h
mmsoftware/mmmail/src/mmsmtpd/mmsmtpd.c
mmsoftware/mmmail/src/mmsmtpd/mmsmtpd.h

index 4d2ddd1..84748d4 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mmpop3d.c,v 1.43 2007/03/17 22:01:33 mmondor Exp $ */
+/* $Id: mmpop3d.c,v 1.44 2007/03/19 09:00:07 mmondor Exp $ */
 
 /*
  * Copyright (C) 2001-2007, Matthew Mondor
@@ -83,7 +83,7 @@
 
 MMCOPYRIGHT("@(#) Copyright (c) 2001-2007\n\
 \tMatthew Mondor. All rights reserved.\n");
-MMRCSID("$Id: mmpop3d.c,v 1.43 2007/03/17 22:01:33 mmondor Exp $");
+MMRCSID("$Id: mmpop3d.c,v 1.44 2007/03/19 09:00:07 mmondor Exp $");
 
 
 
@@ -185,8 +185,6 @@ static fdfuncs gfdf = {
     thread_eintr
 };
 
-static bool pq_threadsafe = FALSE;
-
 
 
 
@@ -377,12 +375,6 @@ main(int argc, char **argv)
     /* mmstr nodes */
     strlist = mmstrinit(malloc, free, 16384 * CONF.ALLOC_BUFFERS);
 
-#if (PGSQL_VERSION >= 820)
-    pq_threadsafe = PQisthreadsafe();
-#else
-    pq_threadsafe = FALSE;
-#endif
-
     if (hash_commands(commands, 3) && POOL_VALID(&clenv_pool) &&
            POOL_VALID(&mutexes_pool) && strlist) {
        thread_init();
@@ -393,7 +385,8 @@ main(int argc, char **argv)
                CONF.SERVER_NAMES, CONF.LISTEN_IPS, uid, gids, ngids,
                CONF.MAX_IPS, CONF.MAX_PER_IP, CONF.CONNECTION_RATE,
                CONF.CONNECTION_PERIOD, CONF.INPUT_TIMEOUT,
-               CONF.LISTEN_PORT, CONF.RESOLVE_HOSTS, handleclient);
+               CONF.LISTEN_PORT, CONF.RESOLVE_HOSTS, handleclient,
+               utdata_constructor, utdata_destructor);
 
        mmfreegidarray(gids);
        ret = 0;
@@ -857,27 +850,37 @@ clenv_constructor(pnode_t *pn)
        mmstat_init(&clenv->vstat, TRUE, TRUE);
        mmstat_init(&clenv->pstat, TRUE, FALSE);
 
-       if (pq_threadsafe) {
-           if ((clenv->pgconn = PQconnectdb(CONF.DB_INFO)) == NULL) {
-               mmsyslog(LOGLEVEL, 0, "PQconnectdb()");
-               return FALSE;
-           }
-       }
-
        return TRUE;
 }
 
+/* ARGSUSED */
 static void
 clenv_destructor(pnode_t *pn)
 {
+       /*
        clientenv       *clenv = (clientenv *)pn;
+       */
 
-       if (pq_threadsafe) {
-           if (clenv->pgconn != NULL) {
-               PQfinish(clenv->pgconn);
-               clenv->pgconn = NULL;
-           }
-       }
+       /* NOOP */
+}
+
+static void *
+utdata_constructor(void)
+{
+       PGconn  *pgconn;
+
+       if ((pgconn = PQconnectdb(CONF.DB_INFO)) == NULL)
+               syslog(LOG_NOTICE, "PQconnectdb()");
+
+       return pgconn;
+}
+
+static void
+utdata_destructor(void *utdata)
+{
+
+       if (utdata != NULL)
+               PQfinish(utdata);
 }
 
 
@@ -891,13 +894,6 @@ alloc_clientenv(void)
     clenv = (clientenv *)pool_alloc(&clenv_pool, TRUE);
     pthread_mutex_unlock(&clenv_lock);
 
-    if (!pq_threadsafe) {
-       if ((clenv->pgconn = PQconnectdb(CONF.DB_INFO)) == NULL) {
-           syslog(LOG_NOTICE, "alloc_clientenv() - PQconnectdb()");
-           return free_clientenv(clenv);
-       }
-    }
-
     return (clenv);
 }
 
@@ -942,11 +938,6 @@ free_clientenv(clientenv *clenv)
     if (clenv->index != NULL)
        free(clenv->index);
 
-    if (!pq_threadsafe) {
-       if (clenv->pgconn != NULL)
-           PQfinish(clenv->pgconn);
-    }
-
     pthread_mutex_lock(&clenv_lock);
     pool_free((pnode_t *)clenv);
     pthread_mutex_unlock(&clenv_lock);
@@ -1420,7 +1411,8 @@ msgwrite(fdbuf *fdb, const void *buf, size_t size)
  */
 static int
 handleclient(unsigned long id, int fd, clientlistnode *clientlnode,
-            struct iface *iface, struct async_clenv *aclenv)
+            struct iface *iface, struct async_clenv *aclenv,
+            void *utdata)
 {
     char buffer[1024], ipaddr[20], *tmp;
     int len, state, nstate, timeout, dstatus;
@@ -1468,6 +1460,7 @@ handleclient(unsigned long id, int fd, clientlistnode *clientlnode,
            clenv->id = id;
            clenv->iface = iface;
            clenv->aclenv = aclenv;
+           clenv->pgconn = utdata;
 
            reply(fdb, TRUE, "%s (%s (%s)) Service ready", iface->hostname,
                    DAEMON_NAME, DAEMON_VERSION);
index 26dc357..dc38ca2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mmpop3d.h,v 1.18 2007/03/16 17:24:10 mmondor Exp $ */
+/* $Id: mmpop3d.h,v 1.19 2007/03/19 09:00:07 mmondor Exp $ */
 
 /*
  * Copyright (C) 2001-2007, Matthew Mondor
@@ -64,7 +64,7 @@
 /* DEFINITIONS */
 
 #define DAEMON_NAME    "mmpop3d"
-#define DAEMON_VERSION "mmmail-0.2.0/mmondor"
+#define DAEMON_VERSION "mmmail-0.2.1/mmondor"
 
 /* Negative states are used by the state swapper, others are real states */
 #define STATE_ERROR    -3
@@ -217,6 +217,8 @@ static bool msgwrite(fdbuf *, const void *, size_t);
 static bool reply(fdbuf *, bool, const char *, ...);
 static bool clenv_constructor(pnode_t *);
 static void clenv_destructor(pnode_t *);
+static void *utdata_constructor(void);
+static void utdata_destructor(void *);
 static clientenv *alloc_clientenv(void);
 static bool init_clientenv(clientenv *);
 static clientenv *free_clientenv(clientenv *);
@@ -225,7 +227,7 @@ static bool valid_host(char *);
 inline static bool valid_char(char);
 
 static int handleclient(unsigned long, int, clientlistnode *, struct iface *,
-       struct async_clenv *);
+       struct async_clenv *, void *);
 
 static void thread_init(void);
 static void *thread_mutex_create(void);
index cf55c70..87c734c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mmsmtpd.c,v 1.77 2007/03/17 22:01:34 mmondor Exp $ */
+/* $Id: mmsmtpd.c,v 1.78 2007/03/19 09:00:10 mmondor Exp $ */
 
 /*
  * Copyright (C) 2001-2007, Matthew Mondor
@@ -82,7 +82,7 @@
 
 MMCOPYRIGHT("@(#) Copyright (c) 2001-2007\n\
 \tMatthew Mondor. All rights reserved.\n");
-MMRCSID("$Id: mmsmtpd.c,v 1.77 2007/03/17 22:01:34 mmondor Exp $");
+MMRCSID("$Id: mmsmtpd.c,v 1.78 2007/03/19 09:00:10 mmondor Exp $");
 
 
 
@@ -153,8 +153,6 @@ static hashtable_t command_table;
 /* Global bandwidth shaping fdb context */
 static fdbcontext fdbc;
 
-static bool pq_threadsafe = FALSE;
-
 /* Quick index to RCPT command replies (see mmsmtpd.h for matching defines) */
 static const struct reply_messages rcpt_msg[RCPT_MAX] = {
     {250, "Recipient ok"},
@@ -517,12 +515,6 @@ main(int argc, char **argv)
     /* mmstr nodes */
     strlist = mmstrinit(malloc, free, 65536 * CONF.ALLOC_BUFFERS);
 
-#if (PGSQL_VERSION >= 820)
-    pq_threadsafe = (bool)PQisthreadsafe();
-#else
-    pq_threadsafe = FALSE;
-#endif
-
     if (hash_commands(commands, 4) && POOL_VALID(&clenv_pool) &&
            POOL_VALID(&rcpt_pool) && POOL_VALID(&mutexes_pool) && strlist &&
            (!CONF.FLOOD_PROTECTION || (POOL_VALID(&hosts_pool) &&
@@ -536,7 +528,8 @@ main(int argc, char **argv)
                CONF.SERVER_NAMES, CONF.LISTEN_IPS, uid, gids, ngids,
                CONF.MAX_IPS, CONF.MAX_PER_IP, CONF.CONNECTION_RATE,
                CONF.CONNECTION_PERIOD, CONF.INPUT_TIMEOUT,
-               CONF.LISTEN_PORT, CONF.RESOLVE_HOSTS, handleclient);
+               CONF.LISTEN_PORT, CONF.RESOLVE_HOSTS, handleclient,
+               utdata_constructor, utdata_destructor);
 
        mmfreegidarray(gids);
        ret = 0;
@@ -1131,27 +1124,38 @@ clientenv_constructor(pnode_t *pn)
     mmstat_init(&clenv->vstat, TRUE, TRUE);
     mmstat_init(&clenv->pstat, TRUE, FALSE);
 
-    if (pq_threadsafe) {
-       if ((clenv->pgconn = PQconnectdb(CONF.DB_INFO)) == NULL) {
-           mmsyslog(LOGLEVEL, 0, "PQconnectdb()");
-           return FALSE;
-       }
-    }
-
     return TRUE;
 }
 
+/* ARGSUSED */
 static void
 clientenv_destructor(pnode_t *pn)
 {
+    /*
     clientenv  *clenv = (clientenv *)pn;
+    */
 
-    if (pq_threadsafe) {
-       if (clenv->pgconn != NULL) {
-           PQfinish(clenv->pgconn);
-           clenv->pgconn = NULL;
-       }
-    }
+    /* NOOP */
+}
+
+
+static void *
+utdata_constructor(void)
+{
+    PGconn     *pgconn;
+
+    if ((pgconn = PQconnectdb(CONF.DB_INFO)) == NULL)
+       syslog(LOG_NOTICE, "PQconnectdb()");
+
+    return pgconn;
+}
+
+static void
+utdata_destructor(void *utdata)
+{
+
+    if (utdata != NULL)
+       PQfinish(utdata);
 }
 
 
@@ -1165,13 +1169,6 @@ alloc_clientenv(void)
     clenv = (clientenv *)pool_alloc(&clenv_pool, TRUE);
     pthread_mutex_unlock(&clenv_lock);
 
-    if (!pq_threadsafe) {
-       if ((clenv->pgconn = PQconnectdb(CONF.DB_INFO)) == NULL) {
-           syslog(LOG_NOTICE, "alloc_clientenv() - PQconnectdb()");
-           return free_clientenv(clenv);
-       }
-    }
-
     return (clenv);
 }
 
@@ -1202,11 +1199,6 @@ free_clientenv(clientenv *clenv)
        mmstrfree(clenv->from);
     empty_rcpts(&clenv->rcpt);
 
-    if (!pq_threadsafe) {
-       if (clenv->pgconn != NULL)
-           PQfinish(clenv->pgconn);
-    }
-
     pthread_mutex_lock(&clenv_lock);
     pool_free((pnode_t *)clenv);
     pthread_mutex_unlock(&clenv_lock);
@@ -2274,7 +2266,7 @@ do_data_queue_notify_connect(void)
  */
 static int
 handleclient(unsigned long id, int fd, clientlistnode *clientlnode,
-       struct iface *iface, struct async_clenv *aclenv)
+       struct iface *iface, struct async_clenv *aclenv, void *utdata)
 {
     char buffer[1024], ipaddr[20], *tmp;
     int len, state, nstate, timeout, dstatus;
@@ -2324,6 +2316,7 @@ handleclient(unsigned long id, int fd, clientlistnode *clientlnode,
            clenv->id = id;
            clenv->iface = iface;
            clenv->aclenv = aclenv;
+           clenv->pgconn = utdata;
 
            reply(fdb, 220, FALSE, "%s (%s (%s)) Service ready",
                    iface->hostname, DAEMON_NAME, DAEMON_VERSION);
index d9668ca..bc796cb 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mmsmtpd.h,v 1.35 2007/03/16 17:24:10 mmondor Exp $ */
+/* $Id: mmsmtpd.h,v 1.36 2007/03/19 09:00:10 mmondor Exp $ */
 
 /*
  * Copyright (C) 2001-2007, Matthew Mondor
@@ -64,7 +64,7 @@
 
 /* DEFINITIONS */
 #define DAEMON_NAME    "mmsmtpd"
-#define DAEMON_VERSION "mmmail-0.2.0/mmondor"
+#define DAEMON_VERSION "mmmail-0.2.1/mmondor"
 
 /* Negative states are used by the state swapper, others are real states */
 #define STATE_ERROR    -3
@@ -279,6 +279,8 @@ static bool reply(fdbuf *, int, bool, const char *, ...);
 
 static bool clientenv_constructor(pnode_t *);
 static void clientenv_destructor(pnode_t *);
+static void *utdata_constructor(void);
+static void utdata_destructor(void *);
 static clientenv *alloc_clientenv(void);
 static bool init_clientenv(clientenv *, bool);
 static clientenv *free_clientenv(clientenv *);
@@ -312,7 +314,7 @@ static void do_data_queue_notify(clientenv *);
 static int do_data_queue_notify_connect(void);
 
 static int handleclient(unsigned long, int, clientlistnode *, struct iface *,
-       struct async_clenv *);
+       struct async_clenv *, void *);
 
 static void thread_init(void);
 static void *thread_mutex_create(void);