File mod_dbd.c-issue18989-autoconnect.dif of Package apache2

--- modules/database/mod_dbd.c.orig	2006-05-18 10:59:22.000000000 -0700
+++ modules/database/mod_dbd.c	2006-05-18 10:57:10.000000000 -0700
@@ -433,6 +432,7 @@
     svr_cfg *svr = ap_get_module_config(s->module_config, &dbd_module);
     apr_status_t rv = APR_SUCCESS;
     const char *errmsg;
+    int tries;
 
     if (!svr->persist) {
         /* Return a once-only connection */
@@ -445,14 +445,33 @@
             return NULL;
         }
     }
-    rv = apr_reslist_acquire(svr->dbpool, &rec);
-    if (rv != APR_SUCCESS) {
-        ap_log_perror(APLOG_MARK, APLOG_ERR, rv, pool,
-                      "Failed to acquire DBD connection from pool!");
-        return NULL;
-    }
-    rv = apr_dbd_check_conn(arec->driver, pool, arec->handle);
-    if ((rv != APR_SUCCESS) && (rv != APR_ENOTIMPL)) {
+    /* PR#39329: implement retries here
+     * How many times to retry?  Well, svr->nkeep is an absolute max
+     * for the number of connections that could've gone stale while
+     * the backend remains up.  I guess it could go above that in
+     * some edge case (the database gets restarted?)
+     * We need 1 try for nkeep = 0 or 1.  Hence the dodgy loop logic.
+     *
+     * This effect of nkeep needs documenting in TFM.
+     */
+
+    tries = svr->nkeep;
+    do {
+        rv = apr_reslist_acquire(svr->dbpool, &rec);
+        if (rv != APR_SUCCESS) {
+            ap_log_perror(APLOG_MARK, APLOG_ERR, rv, pool,
+                          "Failed to acquire DBD connection from pool!");
+            break;
+        }
+        rv = apr_dbd_check_conn(arec->driver, pool, arec->handle);
+        /* mysql wants a second mysql_ping to reopen the connection */
+        if (rv == APR_EGENERAL) {
+            rv = apr_dbd_check_conn(arec->driver, pool, arec->handle);
+        }
+        if ((rv == APR_SUCCESS) || (rv == APR_ENOTIMPL)) {
+            rv = dbd_prepared_init(pool, svr, rec);
+            break;
+        }
         errmsg = apr_dbd_error(arec->driver, arec->handle, rv);
         if (!errmsg) {
             errmsg = "(unknown)";
@@ -460,9 +478,9 @@
         ap_log_perror(APLOG_MARK, APLOG_ERR, rv, pool,
                       "DBD[%s] Error: %s", svr->name, errmsg );
         apr_reslist_invalidate(svr->dbpool, rec);
-        return NULL;
-    }
-    return arec;
+    } while (--tries > 0);
+
+    return ((rv == APR_SUCCESS) || (rv == APR_ENOTIMPL)) ? arec : NULL;
 }
 #else
 DBD_DECLARE_NONSTD(ap_dbd_t*) ap_dbd_open(apr_pool_t *pool, server_rec *s)
openSUSE Build Service is sponsored by