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

📄 apr_memcache.c

📁 Apache官方在今天放出产品系列2.2的最新版本2.2.11的源码包 最流行的HTTP服务器软件之一
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */#include "apr_memcache.h"#include "apr_poll.h"#include "apr_version.h"#include <stdlib.h>#define BUFFER_SIZE 512struct apr_memcache_conn_t{    char *buffer;    apr_size_t blen;    apr_pool_t *p;    apr_socket_t *sock;    apr_bucket_alloc_t *balloc;    apr_bucket_brigade *bb;    apr_bucket_brigade *tb;    apr_memcache_server_t *ms;};                                                          /* Strings for Client Commands */#define MC_EOL "\r\n"#define MC_EOL_LEN (sizeof(MC_EOL)-1)#define MC_WS " "#define MC_WS_LEN (sizeof(MC_WS)-1)#define MC_GET "get "#define MC_GET_LEN (sizeof(MC_GET)-1)#define MC_SET "set "#define MC_SET_LEN (sizeof(MC_SET)-1)#define MC_ADD "add "#define MC_ADD_LEN (sizeof(MC_ADD)-1)#define MC_REPLACE "replace "#define MC_REPLACE_LEN (sizeof(MC_REPLACE)-1)#define MC_DELETE "delete "#define MC_DELETE_LEN (sizeof(MC_DELETE)-1)#define MC_INCR "incr "#define MC_INCR_LEN (sizeof(MC_INCR)-1)#define MC_DECR "decr "#define MC_DECR_LEN (sizeof(MC_DECR)-1)#define MC_VERSION "version"#define MC_VERSION_LEN (sizeof(MC_VERSION)-1)#define MC_STATS "stats"#define MC_STATS_LEN (sizeof(MC_STATS)-1)#define MC_QUIT "quit"#define MC_QUIT_LEN (sizeof(MC_QUIT)-1)/* Strings for Server Replies */#define MS_STORED "STORED"#define MS_STORED_LEN (sizeof(MS_STORED)-1)#define MS_NOT_STORED "NOT_STORED"#define MS_NOT_STORED_LEN (sizeof(MS_NOT_STORED)-1)#define MS_DELETED "DELETED"#define MS_DELETED_LEN (sizeof(MS_DELETED)-1)#define MS_NOT_FOUND "NOT_FOUND"#define MS_NOT_FOUND_LEN (sizeof(MS_NOT_FOUND)-1)#define MS_VALUE "VALUE"#define MS_VALUE_LEN (sizeof(MS_VALUE)-1)#define MS_ERROR "ERROR"#define MS_ERROR_LEN (sizeof(MS_ERROR)-1)#define MS_VERSION "VERSION"#define MS_VERSION_LEN (sizeof(MS_VERSION)-1)#define MS_STAT "STAT"#define MS_STAT_LEN (sizeof(MS_STAT)-1)#define MS_END "END"#define MS_END_LEN (sizeof(MS_END)-1)/** Server and Query Structure for a multiple get */struct cache_server_query_t {    apr_memcache_server_t* ms;    apr_memcache_conn_t* conn;    struct iovec* query_vec;    apr_int32_t query_vec_count;};#define MULT_GET_TIMEOUT 50000static apr_status_t make_server_dead(apr_memcache_t *mc, apr_memcache_server_t *ms){#if APR_HAS_THREADS    apr_thread_mutex_lock(ms->lock);#endif    ms->status = APR_MC_SERVER_DEAD;    ms->btime = apr_time_now();#if APR_HAS_THREADS    apr_thread_mutex_unlock(ms->lock);#endif    return APR_SUCCESS;}static apr_status_t make_server_live(apr_memcache_t *mc, apr_memcache_server_t *ms){    ms->status = APR_MC_SERVER_LIVE;     return APR_SUCCESS;}APU_DECLARE(apr_status_t) apr_memcache_add_server(apr_memcache_t *mc, apr_memcache_server_t *ms){    apr_status_t rv = APR_SUCCESS;    if(mc->ntotal >= mc->nalloc) {        return APR_ENOMEM;    }    mc->live_servers[mc->ntotal] = ms;    mc->ntotal++;    make_server_live(mc, ms);    return rv;}static apr_status_t mc_version_ping(apr_memcache_server_t *ms);APU_DECLARE(apr_memcache_server_t *) apr_memcache_find_server_hash(apr_memcache_t *mc, const apr_uint32_t hash){    if (mc->server_func) {        return mc->server_func(mc->server_baton, mc, hash);    }    else {        return apr_memcache_find_server_hash_default(NULL, mc, hash);    }}   APU_DECLARE(apr_memcache_server_t *) apr_memcache_find_server_hash_default(void *baton, apr_memcache_t *mc,                                      const apr_uint32_t hash){    apr_memcache_server_t *ms = NULL;    apr_uint32_t h = hash ? hash : 1;    apr_uint32_t i = 0;    apr_time_t curtime = 0;       if(mc->ntotal == 0) {        return NULL;    }    do {        ms = mc->live_servers[h % mc->ntotal];        if(ms->status == APR_MC_SERVER_LIVE) {            break;        }        else {            if (curtime == 0) {                curtime = apr_time_now();            }#if APR_HAS_THREADS            apr_thread_mutex_lock(ms->lock);#endif            /* Try the the dead server, every 5 seconds */            if (curtime - ms->btime >  apr_time_from_sec(5)) {                if (mc_version_ping(ms) == APR_SUCCESS) {                    ms->btime = curtime;                    make_server_live(mc, ms);#if APR_HAS_THREADS                    apr_thread_mutex_unlock(ms->lock);#endif                    break;                }            }#if APR_HAS_THREADS            apr_thread_mutex_unlock(ms->lock);#endif        }        h++;        i++;    } while(i < mc->ntotal);    if (i == mc->ntotal) {        ms = NULL;    }    return ms;}APU_DECLARE(apr_memcache_server_t *) apr_memcache_find_server(apr_memcache_t *mc, const char *host, apr_port_t port){    int i;    for (i = 0; i < mc->ntotal; i++) {        if (strcmp(mc->live_servers[i]->host, host) == 0            && mc->live_servers[i]->port == port) {            return mc->live_servers[i];        }    }    return NULL;}static apr_status_t ms_find_conn(apr_memcache_server_t *ms, apr_memcache_conn_t **conn) {#if APR_HAS_THREADS    return apr_reslist_acquire(ms->conns, (void **)conn);#else    *conn = ms->conn;    return APR_SUCCESS;#endif}static apr_status_t ms_bad_conn(apr_memcache_server_t *ms, apr_memcache_conn_t *conn) {#if APR_HAS_THREADS    return apr_reslist_invalidate(ms->conns, conn);#else    return APR_SUCCESS;#endif}static apr_status_t ms_release_conn(apr_memcache_server_t *ms, apr_memcache_conn_t *conn) {#if APR_HAS_THREADS    return apr_reslist_release(ms->conns, conn);#else    return APR_SUCCESS;#endif}APU_DECLARE(apr_status_t) apr_memcache_enable_server(apr_memcache_t *mc, apr_memcache_server_t *ms){    apr_status_t rv = APR_SUCCESS;    if (ms->status == APR_MC_SERVER_LIVE) {        return rv;    }    rv = make_server_live(mc, ms);    return rv;}APU_DECLARE(apr_status_t) apr_memcache_disable_server(apr_memcache_t *mc, apr_memcache_server_t *ms){    return make_server_dead(mc, ms);}static apr_status_t conn_connect(apr_memcache_conn_t *conn){    apr_status_t rv = APR_SUCCESS;    apr_sockaddr_t *sa;    rv = apr_sockaddr_info_get(&sa, conn->ms->host, APR_INET, conn->ms->port, 0, conn->p);    if (rv != APR_SUCCESS) {        return rv;    }    rv = apr_socket_timeout_set(conn->sock, 1 * APR_USEC_PER_SEC);    if (rv != APR_SUCCESS) {        return rv;    }    rv = apr_socket_connect(conn->sock, sa);    if (rv != APR_SUCCESS) {        return rv;    }    rv = apr_socket_timeout_set(conn->sock, -1);    if (rv != APR_SUCCESS) {        return rv;    }    return rv;}static apr_status_t conn_clean(void *data){    apr_memcache_conn_t *conn = data;    struct iovec vec[2];    apr_size_t written;    /* send a quit message to the memcached server to be nice about it. */    vec[0].iov_base = MC_QUIT;    vec[0].iov_len = MC_QUIT_LEN;    vec[1].iov_base = MC_EOL;    vec[1].iov_len = MC_EOL_LEN;        /* Return values not checked, since we just want to make it go away. */    apr_socket_sendv(conn->sock, vec, 2, &written);    apr_socket_close(conn->sock);    conn->p = NULL; /* so that destructor does not destroy the pool again */    return APR_SUCCESS;}static apr_status_tmc_conn_construct(void **conn_, void *params, apr_pool_t *pool){    apr_status_t rv = APR_SUCCESS;    apr_memcache_conn_t *conn;    apr_bucket *e;    apr_pool_t *np;    apr_memcache_server_t *ms = params;    rv = apr_pool_create(&np, pool);    if (rv != APR_SUCCESS) {        return rv;    }#if APR_HAS_THREADS    conn = malloc(sizeof( apr_memcache_conn_t )); /* non-pool space! */#else    conn = apr_palloc(np, sizeof( apr_memcache_conn_t ));#endif    conn->p = np;    rv = apr_socket_create(&conn->sock, APR_INET, SOCK_STREAM, 0, np);    if (rv != APR_SUCCESS) {        apr_pool_destroy(np);#if APR_HAS_THREADS        free(conn);#endif        return rv;    }    conn->balloc = apr_bucket_alloc_create(conn->p);    conn->bb = apr_brigade_create(conn->p, conn->balloc);    conn->tb = apr_brigade_create(conn->p, conn->balloc);    conn->buffer = apr_palloc(conn->p, BUFFER_SIZE);    conn->blen = 0;    conn->ms = ms;    e = apr_bucket_socket_create(conn->sock, conn->balloc);    APR_BRIGADE_INSERT_TAIL(conn->bb, e);    rv = conn_connect(conn);    if (rv != APR_SUCCESS) {        apr_pool_destroy(np);#if APR_HAS_THREADS        free(conn);#endif    }    else {        apr_pool_cleanup_register(np, conn, conn_clean, apr_pool_cleanup_null);        *conn_ = conn;    }        return rv;}#if APR_HAS_THREADSstatic apr_status_tmc_conn_destruct(void *conn_, void *params, apr_pool_t *pool){    apr_memcache_conn_t *conn = (apr_memcache_conn_t*)conn_;        if (conn->p) {        apr_pool_destroy(conn->p);    }    free(conn); /* free non-pool space */        return APR_SUCCESS;}#endifAPU_DECLARE(apr_status_t) apr_memcache_server_create(apr_pool_t *p,                                                      const char *host, apr_port_t port,                                                      apr_uint32_t min, apr_uint32_t smax,                                                     apr_uint32_t max, apr_uint32_t ttl,                                                     apr_memcache_server_t **ms){    apr_status_t rv = APR_SUCCESS;    apr_memcache_server_t *server;    apr_pool_t *np;    rv = apr_pool_create(&np, p);    server = apr_palloc(np, sizeof(apr_memcache_server_t));    server->p = np;    server->host = apr_pstrdup(np, host);    server->port = port;    server->status = APR_MC_SERVER_DEAD;#if APR_HAS_THREADS    rv = apr_thread_mutex_create(&server->lock, APR_THREAD_MUTEX_DEFAULT, np);    if (rv != APR_SUCCESS) {        return rv;    }    rv = apr_reslist_create(&server->conns,                                min,                     /* hard minimum */                               smax,                    /* soft maximum */                               max,                     /* hard maximum */                               ttl,                     /* Time to live */                               mc_conn_construct,       /* Make a New Connection */

⌨️ 快捷键说明

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