apache2/mod_dbd.c-issue18989-autoconnect.dif

66 lines
2.4 KiB
Plaintext
Raw Normal View History

--- 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)