static void test_timeout(abts_case *tc, apr_reslist_t *rl) { apr_status_t rv; my_resource_t *resources[RESLIST_HMAX]; my_resource_t *res; void *vp; int i; apr_reslist_timeout_set(rl, 1000); /* deplete all possible resources from the resource list * so that the next call will block until timeout is reached * (since there are no other threads to make a resource * available) */ for (i = 0; i < RESLIST_HMAX; i++) { rv = apr_reslist_acquire(rl, (void**)&resources[i]); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); } /* next call will block until timeout is reached */ rv = apr_reslist_acquire(rl, &vp); ABTS_TRUE(tc, APR_STATUS_IS_TIMEUP(rv)); res = vp; /* release the resources; otherwise the destroy operation * will blow */ for (i = 0; i < RESLIST_HMAX; i++) { rv = apr_reslist_release(rl, resources[i]); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); } }
/* 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 */ PGconn* pgasp_pool_open(server_rec* s) { PGconn* ret = NULL ; pgasp_config* pgasp = (pgasp_config*) ap_get_module_config(s->module_config, &pgasp_module) ; apr_uint32_t acquired_cnt ; if (pgasp->dbpool == NULL) { pgasp = apr_hash_get(pgasp_pool_config, pgasp->key, APR_HASH_KEY_STRING); } if ( apr_reslist_acquire(pgasp->dbpool, (void**)&ret) != APR_SUCCESS ) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_pgasp: Failed to acquire PgSQL connection from pool!") ; return NULL ; } if (PQstatus(ret) != CONNECTION_OK) { PQreset(ret); if (PQstatus(ret) != CONNECTION_OK) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "PgSQL Error: %s", PQerrorMessage(ret) ) ; apr_reslist_release(pgasp->dbpool, ret) ; return NULL ; } } if (pgasp->nkeep < (acquired_cnt = apr_reslist_acquired_count ( pgasp->dbpool ))) { ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, "mod_pgasp: %d connections in the %s pool acquired (%d,%d,%d)", acquired_cnt, pgasp->key, pgasp->nmin, pgasp->nkeep, pgasp->nmax ) ; } return ret ; }
static void * APR_THREAD_FUNC resource_consuming_thread(apr_thread_t *thd, void *data) { apr_status_t rv; my_thread_info_t *thread_info = data; apr_reslist_t *rl = thread_info->reslist; int i; for (i = 0; i < CONSUMER_ITERATIONS; i++) { my_resource_t *res; rv = apr_reslist_acquire(rl, (void**)&res); if (rv != APR_SUCCESS) { fprintf(stderr, "Failed to retrieve resource from reslist\n"); apr_thread_exit(thd, rv); return NULL; } printf(" [tid:%d,iter:%d] using resource id:%d\n", thread_info->tid, i, res->id); apr_sleep(thread_info->work_delay_sleep); rv = apr_reslist_release(rl, res); if (rv != APR_SUCCESS) { fprintf(stderr, "Failed to return resource to reslist\n"); apr_thread_exit(thd, rv); return NULL; } } return APR_SUCCESS; }
int ml_reslist_acquire(lua_State*L) { request_rec* r = CHECK_REQUEST_OBJECT(1); size_t l; const char* o = luaL_checklstring(L, 2, &l); struct dir_config *d = ap_get_module_config(r->per_dir_config, &luaex_module); apr_reslist_t *reslist = apr_hash_get(d->resource, o, l); void *resource; apr_status_t status = apr_reslist_acquire(reslist, &resource); if (status || resource == NULL) { lua_pushnil(L); lua_pushnumber(L, status); return 2; } *(void**)lua_newuserdata(L, sizeof(void*)) = resource; luaL_getmetatable(L, o); if (lua_istable(L, -1)) { lua_getfield(L, -1, "__gc"); if (lua_isfunction(L, -1)) { lua_pushnil(L); lua_setfield(L, -3, "__gc"); } lua_pop(L, 1); } lua_setmetatable(L, -2); return 1; }
/** * Get redis context on redis pool */ static redisContext* pool_open(server_rec* s) { redisContext *ctx = NULL; redis_cfg *config = (redis_cfg*) ap_get_module_config(s->module_config, &apachelog_module); if (apr_reslist_acquire(config->redis_pool, (void**) &ctx) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "[APACHELOG][GET REDIS CONTEXT FAIL]"); } return ctx; }
static void test_shrinking(abts_case *tc, apr_reslist_t *rl) { apr_status_t rv; my_resource_t *resources[RESLIST_HMAX]; my_resource_t *res; void *vp; int i; int sleep_time = RESLIST_TTL / RESLIST_HMAX; /* deplete all possible resources from the resource list */ for (i = 0; i < RESLIST_HMAX; i++) { rv = apr_reslist_acquire(rl, (void**)&resources[i]); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); } /* Free all resources above RESLIST_SMAX - 1 */ for (i = RESLIST_SMAX - 1; i < RESLIST_HMAX; i++) { rv = apr_reslist_release(rl, resources[i]); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); } for (i = 0; i < RESLIST_HMAX; i++) { rv = apr_reslist_acquire(rl, &vp); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); res = vp; apr_sleep(sleep_time); rv = apr_reslist_release(rl, res); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); } apr_sleep(sleep_time); /* * Now free the remaining elements. This should trigger the shrinking of * the list */ for (i = 0; i < RESLIST_SMAX - 1; i++) { rv = apr_reslist_release(rl, resources[i]); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); } }
static libcouchbase_t* _couchbase_get_connection(mapcache_context *ctx, mapcache_tile *tile) { apr_status_t rv; libcouchbase_t *instance; mapcache_cache_couchbase *cache = (mapcache_cache_couchbase*)tile->tileset->cache; rv = apr_reslist_acquire(cache->connection_pool, (void **)&instance); if(rv != APR_SUCCESS) { ctx->set_error(ctx, 500, "failed to aquire connection to couchbase backend: %s", ctx->get_error_message(ctx)); return NULL; } return instance; }
static struct mc_mapobj* _get_mapboj(mapcache_context *ctx, mapcache_map *map) { apr_status_t rv; mapcache_source_mapserver *src = (mapcache_source_mapserver*) map->tileset->source; struct mc_mapobj *mcmap; apr_reslist_t *mapobjs = NULL; if(!mapobj_container || NULL == (mapobjs = apr_hash_get(mapobj_container,src->source.name,APR_HASH_KEY_STRING))) { #ifdef APR_HAS_THREADS if(ctx->threadlock) apr_thread_mutex_lock((apr_thread_mutex_t*)ctx->threadlock); #endif if(!mapobj_container) { mapobj_container = apr_hash_make(ctx->process_pool); } mapobjs = apr_hash_get(mapobj_container,src->source.name,APR_HASH_KEY_STRING); if(!mapobjs) { apr_status_t rv; rv = apr_reslist_create(&mapobjs, 0 /* min */, 1 /* soft max */, 30 /* hard max */, 6 * 1000000 /*6 seconds, ttl*/, _ms_get_mapobj, /* resource constructor */ _ms_free_mapobj, /* resource destructor */ src, ctx->process_pool); if (rv != APR_SUCCESS) { ctx->set_error(ctx, 500, "failed to create mapobj connection pool for cache %s", src->source.name); #ifdef APR_HAS_THREADS if(ctx->threadlock) apr_thread_mutex_unlock((apr_thread_mutex_t*)ctx->threadlock); #endif return NULL; } apr_hash_set(mapobj_container,src->source.name,APR_HASH_KEY_STRING,mapobjs); } assert(mapobjs); #ifdef APR_HAS_THREADS if(ctx->threadlock) apr_thread_mutex_unlock((apr_thread_mutex_t*)ctx->threadlock); #endif } rv = apr_reslist_acquire(mapobjs, (void **) &mcmap); if (rv != APR_SUCCESS) { ctx->set_error(ctx, 500, "failed to aquire mappObj instance: %s", mcmap->error); return NULL; } return mcmap; }
static struct bdb_env* _bdb_get_conn(mapcache_context *ctx, mapcache_tile* tile, int readonly) { apr_status_t rv; mapcache_cache_bdb *cache = (mapcache_cache_bdb*)tile->tileset->cache; struct bdb_env *benv; apr_reslist_t *pool; if(readonly) pool = cache->ro_connection_pool; else pool = cache->rw_connection_pool; rv = apr_reslist_acquire(pool, (void **)&benv); if(rv != APR_SUCCESS) { ctx->set_error(ctx,500,"failed to aquire connection to bdb backend: %s", cache->ctx->get_error_message(cache->ctx)); cache->ctx->clear_errors(cache->ctx); return NULL; } benv->readonly = readonly; return benv; }
static void * APR_THREAD_FUNC resource_consuming_thread(apr_thread_t *thd, void *data) { int i; apr_uint32_t chance; void *vp; apr_status_t rv; my_resource_t *res; my_thread_info_t *thread_info = data; apr_reslist_t *rl = thread_info->reslist; #if APR_HAS_RANDOM apr_generate_random_bytes((void*)&chance, sizeof(chance)); #else chance = (apr_uint32_t)(apr_time_now() % APR_TIME_C(4294967291)); #endif for (i = 0; i < CONSUMER_ITERATIONS; i++) { rv = apr_reslist_acquire(rl, &vp); ABTS_INT_EQUAL(thread_info->tc, APR_SUCCESS, rv); res = vp; apr_sleep(thread_info->work_delay_sleep); /* simulate a 5% chance of the resource being bad */ chance = lgc(chance); if ( chance < PERCENT95th ) { rv = apr_reslist_release(rl, res); ABTS_INT_EQUAL(thread_info->tc, APR_SUCCESS, rv); } else { rv = apr_reslist_invalidate(rl, res); ABTS_INT_EQUAL(thread_info->tc, APR_SUCCESS, rv); } } return APR_SUCCESS; }
static struct sqlite_conn* _sqlite_get_conn(mapcache_context *ctx, mapcache_tile* tile, int readonly) { apr_status_t rv; mapcache_cache_sqlite *cache = (mapcache_cache_sqlite*) tile->tileset->cache; struct sqlite_conn *conn = NULL; apr_reslist_t *pool = NULL; apr_hash_t *pool_container; if (readonly) { pool_container = ro_connection_pools; } else { pool_container = rw_connection_pools; } if(!pool_container || NULL == (pool = apr_hash_get(pool_container,cache->cache.name, APR_HASH_KEY_STRING)) ) { #ifdef APR_HAS_THREADS if(ctx->threadlock) apr_thread_mutex_lock((apr_thread_mutex_t*)ctx->threadlock); #endif if(!ro_connection_pools) { ro_connection_pools = apr_hash_make(ctx->process_pool); rw_connection_pools = apr_hash_make(ctx->process_pool); } /* probably doesn't exist, unless the previous mutex locked us, so we check */ pool = apr_hash_get(ro_connection_pools,cache->cache.name, APR_HASH_KEY_STRING); if(!pool) { /* there where no existing connection pools, create them*/ rv = apr_reslist_create(&pool, 0 /* min */, 10 /* soft max */, 200 /* hard max */, 60*1000000 /*60 seconds, ttl*/, _sqlite_reslist_get_ro_connection, /* resource constructor */ _sqlite_reslist_free_connection, /* resource destructor */ cache, ctx->process_pool); if(rv != APR_SUCCESS) { ctx->set_error(ctx,500,"failed to create bdb ro connection pool"); #ifdef APR_HAS_THREADS if(ctx->threadlock) apr_thread_mutex_unlock((apr_thread_mutex_t*)ctx->threadlock); #endif return NULL; } apr_hash_set(ro_connection_pools,cache->cache.name,APR_HASH_KEY_STRING,pool); rv = apr_reslist_create(&pool, 0 /* min */, 1 /* soft max */, 1 /* hard max */, 60*1000000 /*60 seconds, ttl*/, _sqlite_reslist_get_rw_connection, /* resource constructor */ _sqlite_reslist_free_connection, /* resource destructor */ cache, ctx->process_pool); if(rv != APR_SUCCESS) { ctx->set_error(ctx,500,"failed to create bdb rw connection pool"); #ifdef APR_HAS_THREADS if(ctx->threadlock) apr_thread_mutex_unlock((apr_thread_mutex_t*)ctx->threadlock); #endif return NULL; } apr_hash_set(rw_connection_pools,cache->cache.name,APR_HASH_KEY_STRING,pool); } #ifdef APR_HAS_THREADS if(ctx->threadlock) apr_thread_mutex_unlock((apr_thread_mutex_t*)ctx->threadlock); #endif if(readonly) pool = apr_hash_get(ro_connection_pools,cache->cache.name, APR_HASH_KEY_STRING); else pool = apr_hash_get(rw_connection_pools,cache->cache.name, APR_HASH_KEY_STRING); assert(pool); } rv = apr_reslist_acquire(pool, (void **) &conn); if (rv != APR_SUCCESS) { ctx->set_error(ctx, 500, "failed to aquire connection to sqlite backend: %s", (conn && conn->errmsg)?conn->errmsg:"unknown error"); return NULL; } return conn; }
/* * This function gets a connection back either by connecting it, or reuse one. */ apr_status_t jxr_conn_open(jaxer_worker* aw, jaxer_connection **pac, request_rec *r) { apr_status_t rv = APR_SUCCESS; *pac = 0; compat_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, "mod_jaxer: entered jxr_conn_open for worker %s", aw->name); if (!aw->ac_cache) { // Create the resource first. Grab the mutex #if APR_HAS_THREADS rv = apr_thread_mutex_lock(aw->mutex); if (rv != APR_SUCCESS) { compat_log_rerror(APLOG_MARK, APLOG_CRIT, rv, r, "mod_jaxer: Failed to acquire thread mutex for jaxerworker %s", aw->name); return rv; } #endif // Make sure it is indeed uncreated if (!aw->ac_cache) { compat_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, "mod_jaxer: jxr_conn_open: creating the connection pool for worker %s", aw->name); rv = jxr_conn_setup(aw); } // Before we do anything else, release the mutex. #if APR_HAS_THREADS if (apr_thread_mutex_unlock(aw->mutex) != APR_SUCCESS) { compat_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, "mod_jaxer: Failed to release thread mutex for jaxerworker %s", aw->name); } #endif if (rv != APR_SUCCESS) { compat_log_rerror(APLOG_MARK, APLOG_CRIT, rv, r, "mod_jaxer: jxr_conn_setup failed for jaxerworker %s", aw->name); return rv; } compat_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, "mod_jaxer: jxr_conn_open: created the connection pool for worker %s", aw->name); } // At this point, we have a cache compat_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, "mod_jaxer: jxr_conn_open: acquiring a connection for worker %s", aw->name); rv = apr_reslist_acquire(aw->ac_cache, (void **)pac); if (rv != APR_SUCCESS) { compat_log_rerror(APLOG_MARK, APLOG_CRIT, rv, r, "mod_jaxer: Failed to acquire connection from pool for jaxerworker %s", aw->name); return rv; } compat_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, "mod_jaxer: jxr_conn_open: acquired a connection (%d) for worker %s", (*pac)->sock, aw->name); // Setup additional parameters (*pac)->request = r; (*pac)->has_error = 0; (*pac)->last_active_time = apr_time_now(); compat_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, "mod_jaxer: jxr_conn_open: checking connection (%d) for worker %s", (*pac)->sock, aw->name); // Make sure it is connected if((rv = jxr_send_begin_request_messsage(*pac, 0)) != APR_SUCCESS && ((rv = jxr_connect_and_begin_request(*pac)) != APR_SUCCESS)) { compat_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r, "mod_jaxer: reuse connection or reconnect failed"); apr_reslist_invalidate(aw->ac_cache, *pac); *pac = 0; return rv; } compat_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, "mod_jaxer: jxr_conn_open: acquiredconnection (%d) successfully for worker %s", (*pac)->sock, aw->name); return rv; }
/** * Function used to create a lua_State instance bound into the web * server in the appropriate scope. */ lua_State *ap_lua_get_lua_state(apr_pool_t *lifecycle_pool, ap_lua_vm_spec *spec, request_rec* r) { lua_State *L = NULL; ap_lua_finfo *cache_info = NULL; int tryCache = 0; if (spec->scope == AP_LUA_SCOPE_SERVER) { char *hash; apr_reslist_t* reslist = NULL; ap_lua_server_spec* sspec = NULL; hash = apr_psprintf(r->pool, "reslist:%s", spec->file); #if APR_HAS_THREADS apr_thread_mutex_lock(ap_lua_mutex); #endif if (apr_pool_userdata_get((void **)&reslist, hash, r->server->process->pool) == APR_SUCCESS) { if (reslist != NULL) { if (apr_reslist_acquire(reslist, (void**) &sspec) == APR_SUCCESS) { L = sspec->L; cache_info = sspec->finfo; } } } if (L == NULL) { ap_lua_vm_spec* server_spec = copy_vm_spec(r->server->process->pool, spec); if ( apr_reslist_create(&reslist, spec->vm_min, spec->vm_max, spec->vm_max, 0, (apr_reslist_constructor) server_vm_construct, (apr_reslist_destructor) server_cleanup_lua, server_spec, r->server->process->pool) == APR_SUCCESS && reslist != NULL) { apr_pool_userdata_set(reslist, hash, NULL, r->server->process->pool); if (apr_reslist_acquire(reslist, (void**) &sspec) == APR_SUCCESS) { L = sspec->L; cache_info = sspec->finfo; } else { return NULL; } } } #if APR_HAS_THREADS apr_thread_mutex_unlock(ap_lua_mutex); #endif } else { if (apr_pool_userdata_get((void **)&L, spec->file, lifecycle_pool) != APR_SUCCESS) { L = NULL; } } if (L == NULL) { ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, APLOGNO(01483) "creating lua_State with file %s", spec->file); /* not available, so create */ if (!vm_construct(&L, spec, lifecycle_pool)) { AP_DEBUG_ASSERT(L != NULL); apr_pool_userdata_set(L, spec->file, cleanup_lua, lifecycle_pool); } } if (spec->codecache == AP_LUA_CACHE_FOREVER || (spec->bytecode && spec->bytecode_len > 0)) { tryCache = 1; } else { char* mkey; if (spec->scope != AP_LUA_SCOPE_SERVER) { mkey = apr_psprintf(r->pool, "ap_lua_modified:%s", spec->file); apr_pool_userdata_get((void **)&cache_info, mkey, lifecycle_pool); if (cache_info == NULL) { cache_info = apr_pcalloc(lifecycle_pool, sizeof(ap_lua_finfo)); apr_pool_userdata_set((void*) cache_info, mkey, NULL, lifecycle_pool); } } if (spec->codecache == AP_LUA_CACHE_STAT) { apr_finfo_t lua_finfo; apr_stat(&lua_finfo, spec->file, APR_FINFO_MTIME|APR_FINFO_SIZE, lifecycle_pool); /* On first visit, modified will be zero, but that's fine - The file is loaded in the vm_construct function. */ if ((cache_info->modified == lua_finfo.mtime && cache_info->size == lua_finfo.size) || cache_info->modified == 0) { tryCache = 1; } cache_info->modified = lua_finfo.mtime; cache_info->size = lua_finfo.size; } else if (spec->codecache == AP_LUA_CACHE_NEVER) { if (cache_info->runs == 0) tryCache = 1; } cache_info->runs++; } if (tryCache == 0 && spec->scope != AP_LUA_SCOPE_ONCE) { int rc; ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, APLOGNO(02332) "(re)loading lua file %s", spec->file); rc = luaL_loadfile(L, spec->file); if (rc != 0) { ap_log_perror(APLOG_MARK, APLOG_ERR, 0, lifecycle_pool, APLOGNO(02333) "Error loading %s: %s", spec->file, rc == LUA_ERRMEM ? "memory allocation error" : lua_tostring(L, 0)); return 0; } lua_pcall(L, 0, LUA_MULTRET, 0); } return L; }
static ftpd_chroot_status_t ftpd_dbi_map_chroot(const request_rec *r, const char **ret_chroot, const char **ret_initroot) { ftpd_chroot_status_t ARV = FTPD_CHROOT_USER_NOT_FOUND; ftpd_dbi_config *conf; const char *query; const char *chroot; ftpd_dbi_rest *dbi_res; dbi_result result; ftpd_dbi_dconfig *dconf = ap_get_module_config(r->per_dir_config, &ftpd_dbi_module); conf = apr_hash_get(ftpd_dbi_config_hash, dconf->id, APR_HASH_KEY_STRING); if (conf == NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[mod_ftpd_dbi.c] - Server Config for \"%s\" was not found", dconf->id); return FTPD_CHROOT_FAIL; } ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "[mod_ftpd_dbi.c] Attempting to Acquire DBI Connection"); apr_reslist_acquire(conf->pool, (void **) &dbi_res); /* make the query to get the user's password */ if (conf->rec.isactive_field) { if (conf->rec.chroot_query == NULL) { query = "SELECT &{ChrootField} FROM &{Table} WHERE &{UsernameField}=&{GivenUsername} AND &{IsActiveField}!=0 LIMIT 0,1"; } else { query = conf->rec.chroot_query; } } else { if (conf->rec.chroot_query == NULL) { query = "SELECT &{ChrootField} FROM &{Table} WHERE &{UsernameField}=&{GivenUsername} LIMIT 0,1"; } else { query = conf->rec.chroot_query; } } /* perform the query */ if ((query = populate_querystring(r, query, conf, dconf, dbi_res, r->user)) && safe_dbi_query(dbi_res, &result, r, query) == 0) { /* store the query result */ if (dbi_result_next_row(result) && dbi_result_get_numrows(result) == 1) { chroot = dbi_result_get_string_copy(result, conf->rec.chroot_field); if ((chroot == NULL) || (strcmp(chroot, "ERROR") == 0)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[mod_ftpd_dbi.c] - libdbi returned an error when retrieving the chroot."); ARV = FTPD_CHROOT_FAIL; } else { // XXXX: Do more checks of the chroot here! *ret_chroot = apr_pstrdup(r->pool, chroot); ARV = FTPD_CHROOT_USER_FOUND; } } else { if (dbi_result_get_numrows(result) == 0) { ARV = FTPD_CHROOT_USER_NOT_FOUND; } else { ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "[mod_ftpd_dbi.c] %lu row(s) was not returned by dbi_result_get_numrows(result)", (unsigned long) dbi_result_get_numrows(result)); ARV = FTPD_CHROOT_FAIL; } } dbi_result_free(result); } else { ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "[mod_ftpd_dbi.c] Query Failed!"); ARV = FTPD_CHROOT_FAIL; } safe_dbi_rel_server(conf->pool, dbi_res, r); return ARV; }