📄 mod_dbd.c
字号:
return dbd_close(sql);}static apr_status_t dbd_setup(apr_pool_t *pool, svr_cfg *svr){ apr_status_t rv; /* create a pool just for the reslist from a process-lifetime pool; * that pool (s->process->pool in the dbd_setup_lock case, * whatever was passed to ap_run_child_init in the dbd_setup_init case) * will be shared with other threads doing other non-mod_dbd things * so we can't use it for the reslist directly */ rv = apr_pool_create(&svr->pool, pool); if (rv != APR_SUCCESS) { ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, pool, "DBD: Failed to create reslist memory pool"); return rv; } rv = apr_reslist_create(&svr->dbpool, svr->nmin, svr->nkeep, svr->nmax, apr_time_from_sec(svr->exptime), dbd_construct, dbd_destruct, svr, svr->pool); if (rv == APR_SUCCESS) { apr_pool_cleanup_register(svr->pool, svr->dbpool, (void*)apr_reslist_destroy, apr_pool_cleanup_null); } else { ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, svr->pool, "DBD: failed to initialise"); apr_pool_destroy(svr->pool); svr->pool = NULL; } return rv;}static apr_status_t dbd_setup_init(apr_pool_t *pool, server_rec *s){ svr_cfg *svr = ap_get_module_config(s->module_config, &dbd_module); apr_status_t rv; if (!svr->persist) { return APR_SUCCESS; } rv = dbd_setup(pool, svr); if (rv == APR_SUCCESS) { return rv; } /* we failed, so create a mutex so that subsequent competing callers * to ap_dbd_open can serialize themselves while they retry */ rv = apr_thread_mutex_create(&svr->mutex, APR_THREAD_MUTEX_DEFAULT, pool); if (rv != APR_SUCCESS) { ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, pool, "DBD: Failed to create thread mutex"); } return rv;}static apr_status_t dbd_setup_lock(apr_pool_t *pool, server_rec *s){ svr_cfg *svr = ap_get_module_config(s->module_config, &dbd_module); apr_status_t rv, rv2 = APR_SUCCESS; /* several threads could be here at the same time, all trying to * initialize the reslist because dbd_setup_init failed to do so */ if (!svr->mutex) { /* we already logged an error when the mutex couldn't be created */ return APR_EGENERAL; } rv = apr_thread_mutex_lock(svr->mutex); if (rv != APR_SUCCESS) { ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, pool, "DBD: Failed to acquire thread mutex"); return rv; } if (!svr->dbpool) { rv2 = dbd_setup(s->process->pool, svr); } rv = apr_thread_mutex_unlock(svr->mutex); if (rv != APR_SUCCESS) { ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, pool, "DBD: Failed to release thread mutex"); if (rv2 == APR_SUCCESS) { rv2 = rv; } } return rv2;}#endif/* Functions we export for modules to use: - open acquires a connection from the pool (opens one if necessary) - close releases it back in to the pool*/DBD_DECLARE_NONSTD(void) ap_dbd_close(server_rec *s, ap_dbd_t *sql){ svr_cfg *svr = ap_get_module_config(s->module_config, &dbd_module); if (!svr->persist) { dbd_close((void*) sql); }#if APR_HAS_THREADS else { apr_reslist_release(svr->dbpool, sql); }#endif}#define arec ((ap_dbd_t*)rec)#if APR_HAS_THREADSDBD_DECLARE_NONSTD(ap_dbd_t*) ap_dbd_open(apr_pool_t *pool, server_rec *s){ void *rec = NULL; svr_cfg *svr = ap_get_module_config(s->module_config, &dbd_module); apr_status_t rv = APR_SUCCESS; const char *errmsg; if (!svr->persist) { /* Return a once-only connection */ rv = dbd_construct(&rec, svr, s->process->pool); return (rv == APR_SUCCESS) ? arec : NULL; } if (!svr->dbpool) { if (dbd_setup_lock(pool, s) != APR_SUCCESS) { 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)) { errmsg = apr_dbd_error(arec->driver, arec->handle, rv); if (!errmsg) { errmsg = "(unknown)"; } 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;}#elseDBD_DECLARE_NONSTD(ap_dbd_t*) ap_dbd_open(apr_pool_t *pool, server_rec *s){ apr_status_t rv = APR_SUCCESS; const char *errmsg; void *rec = NULL; svr_cfg *svr = ap_get_module_config(s->module_config, &dbd_module); if (!svr->persist) { /* Return a once-only connection */ rv = dbd_construct(&rec, svr, s->process->pool); return (rv == APR_SUCCESS) ? arec : NULL; }/* since we're in nothread-land, we can mess with svr->conn with impunity *//* If we have a persistent connection and it's good, we'll use it */ if (svr->conn) { rv = apr_dbd_check_conn(svr->conn->driver, pool, svr->conn->handle); if ((rv != APR_SUCCESS) && (rv != APR_ENOTIMPL)) { errmsg = apr_dbd_error(arec->driver, arec->handle, rv); if (!errmsg) { errmsg = "(unknown)"; } ap_log_perror(APLOG_MARK, APLOG_ERR, rv, pool, "DBD[%s] Error: %s", svr->name, errmsg); svr->conn = NULL; } }/* We don't have a connection right now, so we'll open one */ if (!svr->conn) { if (dbd_construct(&rec, svr, s->process->pool) == APR_SUCCESS) { svr->conn = arec ; apr_pool_cleanup_register(s->process->pool, svr->conn, dbd_close, apr_pool_cleanup_null); } } return svr->conn;}#endif#if APR_HAS_THREADStypedef struct { ap_dbd_t *conn; apr_reslist_t *dbpool;} dbd_pool_rec;static apr_status_t dbd_release(void *REQ){ dbd_pool_rec *req = REQ; apr_reslist_release(req->dbpool, req->conn); return APR_SUCCESS;}DBD_DECLARE_NONSTD(ap_dbd_t *) ap_dbd_acquire(request_rec *r){ svr_cfg *svr; dbd_pool_rec *req = ap_get_module_config(r->request_config, &dbd_module); if (!req) { req = apr_palloc(r->pool, sizeof(dbd_pool_rec)); req->conn = ap_dbd_open(r->pool, r->server); if (req->conn) { svr = ap_get_module_config(r->server->module_config, &dbd_module); ap_set_module_config(r->request_config, &dbd_module, req); if (svr->persist) { req->dbpool = svr->dbpool; apr_pool_cleanup_register(r->pool, req, dbd_release, apr_pool_cleanup_null); } else { apr_pool_cleanup_register(r->pool, req->conn, dbd_close, apr_pool_cleanup_null); } } } return req->conn;}DBD_DECLARE_NONSTD(ap_dbd_t *) ap_dbd_cacquire(conn_rec *c){ svr_cfg *svr; dbd_pool_rec *req = ap_get_module_config(c->conn_config, &dbd_module); if (!req) { req = apr_palloc(c->pool, sizeof(dbd_pool_rec)); req->conn = ap_dbd_open(c->pool, c->base_server); if (req->conn) { svr = ap_get_module_config(c->base_server->module_config, &dbd_module); ap_set_module_config(c->conn_config, &dbd_module, req); if (svr->persist) { req->dbpool = svr->dbpool; apr_pool_cleanup_register(c->pool, req, dbd_release, apr_pool_cleanup_null); } else { apr_pool_cleanup_register(c->pool, req->conn, dbd_close, apr_pool_cleanup_null); } } } return req->conn;}#elseDBD_DECLARE_NONSTD(ap_dbd_t *) ap_dbd_acquire(request_rec *r){ svr_cfg *svr; ap_dbd_t *ret = ap_get_module_config(r->request_config, &dbd_module); if (!ret) { svr = ap_get_module_config(r->server->module_config, &dbd_module); ret = ap_dbd_open(r->pool, r->server); if (ret) { ap_set_module_config(r->request_config, &dbd_module, ret); if (!svr->persist) { apr_pool_cleanup_register(r->pool, svr->conn, dbd_close, apr_pool_cleanup_null); } /* if persist then dbd_open registered cleanup on proc pool */ } } return ret;}DBD_DECLARE_NONSTD(ap_dbd_t *) ap_dbd_cacquire(conn_rec *c){ svr_cfg *svr; ap_dbd_t *ret = ap_get_module_config(c->conn_config, &dbd_module); if (!ret) { svr = ap_get_module_config(c->base_server->module_config, &dbd_module); ret = ap_dbd_open(c->pool, c->base_server); if (ret) { ap_set_module_config(c->conn_config, &dbd_module, ret); if (!svr->persist) { apr_pool_cleanup_register(c->pool, svr->conn, dbd_close, apr_pool_cleanup_null); } /* if persist then dbd_open registered cleanup on proc pool */ } } return ret;}#endifstatic void dbd_hooks(apr_pool_t *pool){#if APR_HAS_THREADS ap_hook_child_init((void*)dbd_setup_init, NULL, NULL, APR_HOOK_MIDDLE);#endif APR_REGISTER_OPTIONAL_FN(ap_dbd_open); APR_REGISTER_OPTIONAL_FN(ap_dbd_close); APR_REGISTER_OPTIONAL_FN(ap_dbd_acquire); APR_REGISTER_OPTIONAL_FN(ap_dbd_cacquire); APR_REGISTER_OPTIONAL_FN(ap_dbd_prepare); apr_dbd_init(pool);}module AP_MODULE_DECLARE_DATA dbd_module = { STANDARD20_MODULE_STUFF, NULL, NULL, dbd_cfg, dbd_merge, dbd_cmds, dbd_hooks};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -