⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_mem_cache.c

📁 apache服务器源代码(版本号:2.2.2)
💻 C
📖 第 1 页 / 共 3 页
字号:
    int eos = 0;    if (mobj->type == CACHE_TYPE_FILE) {        apr_file_t *file = NULL;        int fd = 0;        int other = 0;        /* We can cache an open file descriptor if:         * - the brigade contains one and only one file_bucket &&         * - the brigade is complete &&         * - the file_bucket is the last data bucket in the brigade         */        for (e = APR_BRIGADE_FIRST(b);             e != APR_BRIGADE_SENTINEL(b);             e = APR_BUCKET_NEXT(e))        {            if (APR_BUCKET_IS_EOS(e)) {                eos = 1;            }            else if (APR_BUCKET_IS_FILE(e)) {                apr_bucket_file *a = e->data;                fd++;                file = a->fd;            }            else {                other++;            }        }        if (fd == 1 && !other && eos) {            apr_file_t *tmpfile;            const char *name;            /* Open a new XTHREAD handle to the file */            apr_file_name_get(&name, file);            mobj->flags = ((APR_SENDFILE_ENABLED & apr_file_flags_get(file))                           | APR_READ | APR_BINARY | APR_XTHREAD | APR_FILE_NOCLEANUP);            rv = apr_file_open(&tmpfile, name, mobj->flags,                               APR_OS_DEFAULT, r->pool);            if (rv != APR_SUCCESS) {                return rv;            }            apr_file_inherit_unset(tmpfile);            apr_os_file_get(&(mobj->fd), tmpfile);            /* Open for business */            ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,                         "mem_cache: Cached file: %s with key: %s", name, obj->key);            obj->complete = 1;            return APR_SUCCESS;        }        /* Content not suitable for fd caching. Cache in-memory instead. */        mobj->type = CACHE_TYPE_HEAP;    }    /*     * FD cacheing is not enabled or the content was not     * suitable for fd caching.     */    if (mobj->m == NULL) {        mobj->m = malloc(mobj->m_len);        if (mobj->m == NULL) {            return APR_ENOMEM;        }        obj->count = 0;    }    cur = (char*) mobj->m + obj->count;    /* Iterate accross the brigade and populate the cache storage */    for (e = APR_BRIGADE_FIRST(b);         e != APR_BRIGADE_SENTINEL(b);         e = APR_BUCKET_NEXT(e))    {        const char *s;        apr_size_t len;        if (APR_BUCKET_IS_EOS(e)) {            if (mobj->m_len > obj->count) {                /* Caching a streamed response. Reallocate a buffer of the                 * correct size and copy the streamed response into that                 * buffer */                char *buf = malloc(obj->count);                if (!buf) {                    return APR_ENOMEM;                }                memcpy(buf, mobj->m, obj->count);                free(mobj->m);                mobj->m = buf;                /* Now comes the crufty part... there is no way to tell the                 * cache that the size of the object has changed. We need                 * to remove the object, update the size and re-add the                 * object, all under protection of the lock.                 */                if (sconf->lock) {                    apr_thread_mutex_lock(sconf->lock);                }                /* Has the object been ejected from the cache?                 */                tobj = (cache_object_t *) cache_find(sconf->cache_cache, obj->key);                if (tobj == obj) {                    /* Object is still in the cache, remove it, update the len field then                     * replace it under protection of sconf->lock.                     */                    cache_remove(sconf->cache_cache, obj);                    /* For illustration, cache no longer has reference to the object                     * so decrement the refcount                     * apr_atomic_dec32(&obj->refcount);                     */                    mobj->m_len = obj->count;                    cache_insert(sconf->cache_cache, obj);                    /* For illustration, cache now has reference to the object, so                     * increment the refcount                     * apr_atomic_inc32(&obj->refcount);                     */                }                else if (tobj) {                    /* Different object with the same key found in the cache. Doing nothing                     * here will cause the object refcount to drop to 0 in decrement_refcount                     * and the object will be cleaned up.                     */                } else {                    /* Object has been ejected from the cache, add it back to the cache */                    mobj->m_len = obj->count;                    cache_insert(sconf->cache_cache, obj);                    apr_atomic_inc32(&obj->refcount);                }                if (sconf->lock) {                    apr_thread_mutex_unlock(sconf->lock);                }            }            /* Open for business */            ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,                         "mem_cache: Cached url: %s", obj->key);            obj->complete = 1;            break;        }        rv = apr_bucket_read(e, &s, &len, eblock);        if (rv != APR_SUCCESS) {            return rv;        }        if (len) {            /* Check for buffer overflow */           if ((obj->count + len) > mobj->m_len) {               return APR_ENOMEM;           }           else {               memcpy(cur, s, len);               cur+=len;               obj->count+=len;           }        }        /* This should not fail, but if it does, we are in BIG trouble         * cause we just stomped all over the heap.         */        AP_DEBUG_ASSERT(obj->count <= mobj->m_len);    }    return APR_SUCCESS;}/** * Configuration and start-up */static int mem_cache_post_config(apr_pool_t *p, apr_pool_t *plog,                                 apr_pool_t *ptemp, server_rec *s){    int threaded_mpm;    /* Sanity check the cache configuration */    if (sconf->min_cache_object_size >= sconf->max_cache_object_size) {        ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s,                     "MCacheMaxObjectSize must be greater than MCacheMinObjectSize");        return DONE;    }    if (sconf->max_cache_object_size >= sconf->max_cache_size) {        ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s,                     "MCacheSize must be greater than MCacheMaxObjectSize");        return DONE;    }    if (sconf->max_streaming_buffer_size > sconf->max_cache_object_size) {        /* Issue a notice only if something other than the default config         * is being used */        if (sconf->max_streaming_buffer_size != DEFAULT_MAX_STREAMING_BUFFER_SIZE &&            sconf->max_cache_object_size != DEFAULT_MAX_CACHE_OBJECT_SIZE) {            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s,                         "MCacheMaxStreamingBuffer must be less than or equal to MCacheMaxObjectSize. "                         "Resetting MCacheMaxStreamingBuffer to MCacheMaxObjectSize.");        }        sconf->max_streaming_buffer_size = sconf->max_cache_object_size;    }    if (sconf->max_streaming_buffer_size < sconf->min_cache_object_size) {        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,                     "MCacheMaxStreamingBuffer must be greater than or equal to MCacheMinObjectSize. "                     "Resetting MCacheMaxStreamingBuffer to MCacheMinObjectSize.");        sconf->max_streaming_buffer_size = sconf->min_cache_object_size;    }    ap_mpm_query(AP_MPMQ_IS_THREADED, &threaded_mpm);    if (threaded_mpm) {        apr_thread_mutex_create(&sconf->lock, APR_THREAD_MUTEX_DEFAULT, p);    }    sconf->cache_cache = cache_init(sconf->max_object_cnt,                                    sconf->max_cache_size,                                    memcache_get_priority,                                    sconf->cache_remove_algorithm,                                    memcache_get_pos,                                    memcache_set_pos,                                    memcache_inc_frequency,                                    memcache_cache_get_size,                                    memcache_cache_get_key,                                    memcache_cache_free);    apr_pool_cleanup_register(p, sconf, cleanup_cache_mem, apr_pool_cleanup_null);    if (sconf->cache_cache)        return OK;    return -1;}static const char*set_max_cache_size(cmd_parms *parms, void *in_struct_ptr, const char *arg){    apr_size_t val;    if (sscanf(arg, "%" APR_SIZE_T_FMT, &val) != 1) {        return "MCacheSize argument must be an integer representing the max cache size in KBytes.";    }    sconf->max_cache_size = val*1024;    return NULL;}static const char*set_min_cache_object_size(cmd_parms *parms, void *in_struct_ptr, const char *arg){    apr_size_t val;    if (sscanf(arg, "%" APR_SIZE_T_FMT, &val) != 1) {        return "MCacheMinObjectSize value must be an integer (bytes)";    }    sconf->min_cache_object_size = val;    return NULL;}static const char*set_max_cache_object_size(cmd_parms *parms, void *in_struct_ptr, const char *arg){    apr_size_t val;    if (sscanf(arg, "%" APR_SIZE_T_FMT, &val) != 1) {        return "MCacheMaxObjectSize value must be an integer (bytes)";    }    sconf->max_cache_object_size = val;    return NULL;}static const char*set_max_object_count(cmd_parms *parms, void *in_struct_ptr, const char *arg){    apr_size_t val;    if (sscanf(arg, "%" APR_SIZE_T_FMT, &val) != 1) {        return "MCacheMaxObjectCount value must be an integer";    }    sconf->max_object_cnt = val;    return NULL;}static const char*set_cache_removal_algorithm(cmd_parms *parms, void *name, const char *arg){    if (strcasecmp("LRU", arg)) {        sconf->cache_remove_algorithm = memcache_lru_algorithm;    }    else {        if (strcasecmp("GDSF", arg)) {            sconf->cache_remove_algorithm = memcache_gdsf_algorithm;        }        else {            return "currently implemented algorithms are LRU and GDSF";        }    }    return NULL;}static const char *set_max_streaming_buffer(cmd_parms *parms, void *dummy,                                            const char *arg){    char *err;    if (apr_strtoff(&sconf->max_streaming_buffer_size, arg, &err, 10) || *err) {        return "MCacheMaxStreamingBuffer value must be a number";    }    return NULL;}static const command_rec cache_cmds[] ={    AP_INIT_TAKE1("MCacheSize", set_max_cache_size, NULL, RSRC_CONF,     "The maximum amount of memory used by the cache in KBytes"),    AP_INIT_TAKE1("MCacheMaxObjectCount", set_max_object_count, NULL, RSRC_CONF,     "The maximum number of objects allowed to be placed in the cache"),    AP_INIT_TAKE1("MCacheMinObjectSize", set_min_cache_object_size, NULL, RSRC_CONF,     "The minimum size (in bytes) of an object to be placed in the cache"),    AP_INIT_TAKE1("MCacheMaxObjectSize", set_max_cache_object_size, NULL, RSRC_CONF,     "The maximum size (in bytes) of an object to be placed in the cache"),    AP_INIT_TAKE1("MCacheRemovalAlgorithm", set_cache_removal_algorithm, NULL, RSRC_CONF,     "The algorithm used to remove entries from the cache (default: GDSF)"),    AP_INIT_TAKE1("MCacheMaxStreamingBuffer", set_max_streaming_buffer, NULL, RSRC_CONF,     "Maximum number of bytes of content to buffer for a streamed response"),    {NULL}};static const cache_provider cache_mem_provider ={    &remove_entity,    &store_headers,    &store_body,    &recall_headers,    &recall_body,    &create_mem_entity,    &open_entity,    &remove_url,};static const cache_provider cache_fd_provider ={    &remove_entity,    &store_headers,    &store_body,    &recall_headers,    &recall_body,    &create_fd_entity,    &open_entity,    &remove_url,};static void register_hooks(apr_pool_t *p){    ap_hook_post_config(mem_cache_post_config, NULL, NULL, APR_HOOK_MIDDLE);    /* cache initializer */    /* cache_hook_init(cache_mem_init, NULL, NULL, APR_HOOK_MIDDLE);  */    /*    cache_hook_create_entity(create_entity, NULL, NULL, APR_HOOK_MIDDLE);    cache_hook_open_entity(open_entity,  NULL, NULL, APR_HOOK_MIDDLE);    cache_hook_remove_url(remove_url, NULL, NULL, APR_HOOK_MIDDLE);    */    ap_register_provider(p, CACHE_PROVIDER_GROUP, "mem", "0",                         &cache_mem_provider);    ap_register_provider(p, CACHE_PROVIDER_GROUP, "fd", "0",                         &cache_fd_provider);}module AP_MODULE_DECLARE_DATA mem_cache_module ={    STANDARD20_MODULE_STUFF,    NULL,                    /* create per-directory config structure */    NULL,                    /* merge per-directory config structures */    create_cache_config,     /* create per-server config structure */    NULL,                    /* merge per-server config structures */    cache_cmds,              /* command apr_table_t */    register_hooks};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -