View | Details | Raw Unified | Return to bug 39329
Collapse All | Expand All

(-)modules/database/mod_dbd.c (-11 / +26 lines)
Lines 433-438 Link Here
433
    svr_cfg *svr = ap_get_module_config(s->module_config, &dbd_module);
433
    svr_cfg *svr = ap_get_module_config(s->module_config, &dbd_module);
434
    apr_status_t rv = APR_SUCCESS;
434
    apr_status_t rv = APR_SUCCESS;
435
    const char *errmsg;
435
    const char *errmsg;
436
    int tries;
436
437
437
    if (!svr->persist) {
438
    if (!svr->persist) {
438
        /* Return a once-only connection */
439
        /* Return a once-only connection */
Lines 445-458 Link Here
445
            return NULL;
446
            return NULL;
446
        }
447
        }
447
    }
448
    }
448
    rv = apr_reslist_acquire(svr->dbpool, &rec);
449
    /* PR#39329: implement retries here
449
    if (rv != APR_SUCCESS) {
450
     * How many times to retry?  Well, svr->nkeep is an absolute max
450
        ap_log_perror(APLOG_MARK, APLOG_ERR, rv, pool,
451
     * for the number of connections that could've gone stale while
451
                      "Failed to acquire DBD connection from pool!");
452
     * the backend remains up.  I guess it could go above that in
452
        return NULL;
453
     * some edge case (the database gets restarted?)
453
    }
454
     * We need 1 try for nkeep = 0 or 1.  Hence the dodgy loop logic.
454
    rv = apr_dbd_check_conn(arec->driver, pool, arec->handle);
455
     *
455
    if ((rv != APR_SUCCESS) && (rv != APR_ENOTIMPL)) {
456
     * This effect of nkeep needs documenting in TFM.
457
     */
458
459
    tries = svr->nkeep;
460
    do {
461
        rv = apr_reslist_acquire(svr->dbpool, &rec);
462
        if (rv != APR_SUCCESS) {
463
            ap_log_perror(APLOG_MARK, APLOG_ERR, rv, pool,
464
                          "Failed to acquire DBD connection from pool!");
465
            break;
466
        }
467
        rv = apr_dbd_check_conn(arec->driver, pool, arec->handle);
468
	if ((rv == APR_SUCCESS) || (rv == APR_ENOTIMPL)) {
469
            break;
470
	}
456
        errmsg = apr_dbd_error(arec->driver, arec->handle, rv);
471
        errmsg = apr_dbd_error(arec->driver, arec->handle, rv);
457
        if (!errmsg) {
472
        if (!errmsg) {
458
            errmsg = "(unknown)";
473
            errmsg = "(unknown)";
Lines 460-468 Link Here
460
        ap_log_perror(APLOG_MARK, APLOG_ERR, rv, pool,
475
        ap_log_perror(APLOG_MARK, APLOG_ERR, rv, pool,
461
                      "DBD[%s] Error: %s", svr->name, errmsg );
476
                      "DBD[%s] Error: %s", svr->name, errmsg );
462
        apr_reslist_invalidate(svr->dbpool, rec);
477
        apr_reslist_invalidate(svr->dbpool, rec);
463
        return NULL;
478
    } while (--tries > 0);
464
    }
479
465
    return arec;
480
    return ((rv == APR_SUCCESS) || (rv == APR_ENOTIMPL)) ? arec : NULL;
466
}
481
}
467
#else
482
#else
468
DBD_DECLARE_NONSTD(ap_dbd_t*) ap_dbd_open(apr_pool_t *pool, server_rec *s)
483
DBD_DECLARE_NONSTD(ap_dbd_t*) ap_dbd_open(apr_pool_t *pool, server_rec *s)

Return to bug 39329