static void test_thread_rwlock(abts_case *tc, void *data) { apr_thread_t *t1, *t2, *t3, *t4; apr_status_t s1, s2, s3, s4; s1 = apr_thread_rwlock_create(&rwlock, p); if (s1 == APR_ENOTIMPL) { ABTS_NOT_IMPL(tc, "rwlocks not implemented"); return; } APR_ASSERT_SUCCESS(tc, "rwlock_create", s1); ABTS_PTR_NOTNULL(tc, rwlock); i = 0; x = 0; s1 = apr_thread_create(&t1, NULL, thread_rwlock_func, NULL, p); APR_ASSERT_SUCCESS(tc, "create thread 1", s1); s2 = apr_thread_create(&t2, NULL, thread_rwlock_func, NULL, p); APR_ASSERT_SUCCESS(tc, "create thread 2", s2); s3 = apr_thread_create(&t3, NULL, thread_rwlock_func, NULL, p); APR_ASSERT_SUCCESS(tc, "create thread 3", s3); s4 = apr_thread_create(&t4, NULL, thread_rwlock_func, NULL, p); APR_ASSERT_SUCCESS(tc, "create thread 4", s4); apr_thread_join(&s1, t1); apr_thread_join(&s2, t2); apr_thread_join(&s3, t3); apr_thread_join(&s4, t4); ABTS_INT_EQUAL(tc, MAX_ITER, x); apr_thread_rwlock_destroy(rwlock); }
/* return -1 means error */ static int init_per_local_file_directive_data (request_rec *r, LOCAL_FILE_INFO *p_local_file_info) { apr_status_t rv; char errmsg_buf[120]; auth_remote_svr_conf *svr_conf = ap_get_module_config(r->server->module_config, &auth_remote_module); if (!(p_local_file_info->subpool)) { /* create subpool */ apr_status_t rv = apr_pool_create (&(p_local_file_info->subpool), svr_conf->subpool); if (rv != APR_SUCCESS) { apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf)); ap_log_rerror (APLOG_MARK, APLOG_ERR, 0, r, "fail to create subpool for local file: %s", errmsg_buf); return -1; } } #if APR_HAS_THREADS if (!(p_local_file_info->rwlock)) { /* create rwlock */ rv = apr_thread_rwlock_create (&(p_local_file_info->rwlock), svr_conf->subpool); if (rv != APR_SUCCESS) { apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf)); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "fail to initialize rwlock for local file: %s", errmsg_buf); return -1; } } #endif return 0; }
static cache * cacheCreate (int maxsize, int timeout, unsigned long hash, request_data *rd) /*{{{ */ { // create pool for cache to live in apr_status_t s; apr_pool_t *p; s = apr_pool_create (&p, (apr_pool_t *) NULL); if (s != APR_SUCCESS) { ap_log_error(APLOG_MARK,LOG_WARNING,0,rd->server,"cacheCreate: could not create memory pool"); raise_exn ((int) &exn_OVERFLOW); } cache *c = (cache *) apr_palloc (p, sizeof (cache)); if (c == NULL) { ap_log_error(APLOG_MARK,LOG_WARNING,0,rd->server,"cacheCreate: could not allocate memory from pool"); raise_exn ((int) &exn_OVERFLOW); } ap_log_error(APLOG_MARK,LOG_DEBUG,0,rd->server,"cacheCreate: 0x%x", (unsigned int) c); c->pool = p; c->hashofname = hash; apr_proc_mutex_lock(rd->ctx->cachelock.plock); unsigned long cachehash = hash % rd->ctx->cachelock.shmsize; c->version = rd->ctx->cachelock.version[cachehash]; apr_proc_mutex_unlock(rd->ctx->cachelock.plock); // setup locks apr_thread_rwlock_create (&(c->rwlock), c->pool); apr_thread_mutex_create (&(c->mutex), APR_THREAD_MUTEX_DEFAULT, c->pool); // setup linked list c->sentinel = (entry *) apr_palloc (c->pool, sizeof (entry)); c->sentinel->up = c->sentinel; c->sentinel->down = c->sentinel; c->sentinel->key = NULL; // c->sentinel->key.hash = 0; c->sentinel->data = NULL; c->sentinel->size = 0; // setup hashtable & binary heap c->htable = (entrytable_hashtable_t *) apr_palloc (c->pool, sizeof (entrytable_hashtable_t) + sizeof(cacheheap_binaryheap_t)); c->heap = (cacheheap_binaryheap_t *) (c->htable + 1); entrytable_init (c->htable); cacheheap_heapinit(c->heap); // calculate size c->size = c->htable->hashTableSize * sizeof (entrytable_hashelement_t); c->maxsize = maxsize; // set timeout scheme c->timeout = timeout; return c; } /*}}} */
void globalCacheTableInit (void *rd1) /*{{{ */ { request_data *rd = (request_data *) rd1; rd->cachetable = (cache_hashtable_with_lock *) apr_palloc (rd->pool, sizeof (cache_hashtable_with_lock)); rd->cachetable->ht = (cachetable_hashtable_t *) apr_palloc (rd->pool, sizeof (cachetable_hashtable_t)); rd->cachetable->pool = rd->pool; apr_thread_rwlock_create (&(rd->cachetable->rwlock), rd->pool); cachetable_init (rd->cachetable->ht); } /*}}} */
/* return -1 means error */ static int init_per_url_directive_data (request_rec *r, REMOTE_INFO *p_remote_info) { apr_status_t rv; char errmsg_buf[120]; auth_remote_svr_conf *svr_conf = ap_get_module_config(r->server->module_config, &auth_remote_module); if (!(p_remote_info->subpool)) { /* create subpool */ apr_status_t rv = apr_pool_create (&(p_remote_info->subpool), svr_conf->subpool); if (rv != APR_SUCCESS) { apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf)); ap_log_rerror (APLOG_MARK, APLOG_ERR, 0, r, "fail to create subpool for url: %s", errmsg_buf); return -1; } } if (!(p_remote_info->last_update_time)) { /* init last_update_time */ p_remote_info->last_update_time = apr_palloc (p_remote_info->subpool, APR_RFC822_DATE_LEN); rv = apr_rfc822_date (p_remote_info->last_update_time, 0); if (rv != APR_SUCCESS) { apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf)); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "fail to initialize last_update_time: %s", errmsg_buf); return -1; } #ifdef DEBUG ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "init_last_update_time: %s", p_remote_info->last_update_time); #endif } #if APR_HAS_THREADS if (!(p_remote_info->rwlock)) { /* create rwlock */ rv = apr_thread_rwlock_create (&(p_remote_info->rwlock), svr_conf->subpool); if (rv != APR_SUCCESS) { apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf)); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "fail to initialize rwlock for url : %s", errmsg_buf); return -1; } } #endif return 0; }
int test_thread_rwlock(int num_threads) { apr_thread_t *t[MAX_THREADS]; apr_status_t s[MAX_THREADS]; apr_time_t time_start, time_stop; int i; mutex_counter = 0; printf("apr_thread_rwlock_t Tests\n"); printf("%-60s", " Initializing the apr_thread_rwlock_t"); s[0] = apr_thread_rwlock_create(&thread_rwlock, pool); if (s[0] != APR_SUCCESS) { printf("Failed!\n"); return s[0]; } printf("OK\n"); apr_thread_rwlock_wrlock(thread_rwlock); /* set_concurrency(4)? -aaron */ printf(" Starting %d threads ", num_threads); for (i = 0; i < num_threads; ++i) { s[i] = apr_thread_create(&t[i], NULL, thread_rwlock_func, NULL, pool); if (s[i] != APR_SUCCESS) { printf("Failed!\n"); return s[i]; } } printf("OK\n"); time_start = apr_time_now(); apr_thread_rwlock_unlock(thread_rwlock); /* printf("%-60s", " Waiting for threads to exit"); */ for (i = 0; i < num_threads; ++i) { apr_thread_join(&s[i], t[i]); } /* printf("OK\n"); */ time_stop = apr_time_now(); printf("microseconds: %" APR_INT64_T_FMT " usec\n", (time_stop - time_start)); if (mutex_counter != MAX_COUNTER * num_threads) printf("error: counter = %ld\n", mutex_counter); return APR_SUCCESS; }
SWITCH_DECLARE(switch_status_t) switch_thread_rwlock_create(switch_thread_rwlock_t ** rwlock, switch_memory_pool_t *pool) { return apr_thread_rwlock_create(rwlock, pool); }
int cstat (NXPathCtx_t ctx, char *path, struct stat *buf, unsigned long requestmap, apr_pool_t *p) { apr_pool_t *gPool = (apr_pool_t *)getGlobalPool(); apr_hash_t *statCache = NULL; apr_thread_rwlock_t *rwlock = NULL; NXPathCtx_t pathctx = 0; char *ptr = NULL, *tr; int len = 0, x; char *ppath; char *pinfo; if (ctx == 1) { /* If there isn't a global pool then just stat the file and return */ if (!gPool) { char poolname[50]; if (apr_pool_create(&gPool, NULL) != APR_SUCCESS) { return getstat(ctx, path, buf, requestmap); } setGlobalPool(gPool); apr_pool_tag(gPool, apr_pstrdup(gPool, "cstat_mem_pool")); statCache = apr_hash_make(gPool); apr_pool_userdata_set ((void*)statCache, "STAT_CACHE", stat_cache_cleanup, gPool); apr_thread_rwlock_create(&rwlock, gPool); apr_pool_userdata_set ((void*)rwlock, "STAT_CACHE_LOCK", apr_pool_cleanup_null, gPool); } else { apr_pool_userdata_get((void**)&statCache, "STAT_CACHE", gPool); apr_pool_userdata_get((void**)&rwlock, "STAT_CACHE_LOCK", gPool); } if (!gPool || !statCache || !rwlock) { return getstat(ctx, path, buf, requestmap); } for (x = 0,tr = path;*tr != '\0';tr++,x++) { if (*tr == '\\' || *tr == '/') { ptr = tr; len = x; } if (*tr == ':') { ptr = "\\"; len = x; } } if (ptr) { ppath = apr_pstrndup (p, path, len); strlwr(ppath); if (ptr[1] != '\0') { ptr++; } /* If the path ended in a trailing slash then our result path will be a single slash. To avoid stat'ing the root with a slash, we need to make sure we stat the current directory with a dot */ if (((*ptr == '/') || (*ptr == '\\')) && (*(ptr+1) == '\0')) { pinfo = apr_pstrdup (p, "."); } else { pinfo = apr_pstrdup (p, ptr); } } /* If we have a statCache then try to pull the information from the cache. Otherwise just stat the file and return.*/ if (statCache) { apr_thread_rwlock_rdlock(rwlock); pathctx = (NXPathCtx_t) apr_hash_get(statCache, ppath, APR_HASH_KEY_STRING); apr_thread_rwlock_unlock(rwlock); if (pathctx) { return getstat(pathctx, pinfo, buf, requestmap); } else { int err; err = NXCreatePathContext(0, ppath, 0, NULL, &pathctx); if (!err) { apr_thread_rwlock_wrlock(rwlock); apr_hash_set(statCache, apr_pstrdup(gPool,ppath) , APR_HASH_KEY_STRING, (void*)pathctx); apr_thread_rwlock_unlock(rwlock); return getstat(pathctx, pinfo, buf, requestmap); } } } } return getstat(ctx, path, buf, requestmap); }