Commit 4536459f authored by Jim Jagielski's avatar Jim Jagielski
Browse files

Move some "nice to be able to change" balancer stuff to shm

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1065748 13f79535-47bb-0310-9956-ffa450edef68
parent 38761212
Loading
Loading
Loading
Loading
+1 −1
Changes for configure.in: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -529,7 +529,7 @@ AC_ARG_ENABLE(maintainer-mode,APACHE_HELP_STRING(--enable-maintainer-mode,Turn o
[
  APR_ADDTO(CPPFLAGS, -DAP_DEBUG)
  if test "$GCC" = "yes"; then
    APR_ADDTO(CFLAGS,[-Wall -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Wpointer-arith])
    APR_ADDTO(CFLAGS,[-Wall -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Wpointer-arith -O0])
    AC_CACHE_CHECK([whether gcc accepts -Wdeclaration-after-statement], [ap_cv_cc_Wdas], [
      save_CFLAGS=$CFLAGS
      CFLAGS="$CFLAGS -Wdeclaration-after-statement"
+37 −32
Changes for modules/proxy/mod_proxy.c: 37 added lines, 32 removed lines.
Original line number Diff line number Diff line
@@ -316,11 +316,14 @@ static const char *set_balancer_param(proxy_server_conf *conf,
         * Set to something like JSESSIONID or
         * PHPSESSIONID, etc..,
         */
        path = apr_pstrdup(p, val);
        balancer->sticky = balancer->sticky_path = path;
        if ((path = strchr(path, '|'))) {
        if (strlen(val) > (PROXY_BALANCER_MAX_STICKY_SIZE-1))
            return "stickysession length must be < 64 characters";
        PROXY_STRNCPY(balancer->s->sticky_path, val);
        PROXY_STRNCPY(balancer->s->sticky, val);
        
        if ((path = strchr((char *)val, '|'))) {
            *path++ = '\0';
            balancer->sticky_path = path;
            PROXY_STRNCPY(balancer->s->sticky_path, path);
        }
    }
    else if (!strcasecmp(key, "nofailover")) {
@@ -329,9 +332,9 @@ static const char *set_balancer_param(proxy_server_conf *conf,
         * disabled.
         */
        if (!strcasecmp(val, "on"))
            balancer->sticky_force = 1;
            balancer->s->sticky_force = 1;
        else if (!strcasecmp(val, "off"))
            balancer->sticky_force = 0;
            balancer->s->sticky_force = 0;
        else
            return "failover must be On|Off";
    }
@@ -344,7 +347,7 @@ static const char *set_balancer_param(proxy_server_conf *conf,
        ival = atoi(val);
        if (ival < 1)
            return "timeout must be at least one second";
        balancer->timeout = apr_time_from_sec(ival);
        balancer->s->timeout = apr_time_from_sec(ival);
    }
    else if (!strcasecmp(key, "maxattempts")) {
        /* Maximum number of failover attempts before
@@ -353,8 +356,8 @@ static const char *set_balancer_param(proxy_server_conf *conf,
        ival = atoi(val);
        if (ival < 0)
            return "maximum number of attempts must be a positive number";
        balancer->max_attempts = ival;
        balancer->max_attempts_set = 1;
        balancer->s->max_attempts = ival;
        balancer->s->max_attempts_set = 1;
    }
    else if (!strcasecmp(key, "lbmethod")) {
        proxy_balancer_method *provider;
@@ -371,9 +374,9 @@ static const char *set_balancer_param(proxy_server_conf *conf,
         * mod_jk)
         */
        if (!strcasecmp(val, "on"))
            balancer->scolonsep = 1;
            balancer->s->scolonsep = 1;
        else if (!strcasecmp(val, "off"))
            balancer->scolonsep = 0;
            balancer->s->scolonsep = 0;
        else
            return "scolonpathdelim must be On|Off";
    }
@@ -401,14 +404,14 @@ static const char *set_balancer_param(proxy_server_conf *conf,
    }
    else if (!strcasecmp(key, "nonce")) {
        if (!strcasecmp(val, "None")) {
            *balancer->nonce = '\0';
            *balancer->s->nonce = '\0';
        } 
        else {
            if (strlen(val) > sizeof(balancer->nonce)-1) {
            if (strlen(val) > sizeof(balancer->s->nonce)-1) {
                return "Provided nonce is too large";
            }
            else {
                apr_cpystrn(balancer->nonce, val, sizeof(balancer->nonce));
                PROXY_STRNCPY(balancer->s->nonce, val);
            }
        }
    }
@@ -1007,8 +1010,8 @@ static int proxy_handler(request_rec *r)
            ap_proxy_initialize_worker(worker, r->server, conf->pool);
        }

        if (balancer && balancer->max_attempts_set && !max_attempts)
            max_attempts = balancer->max_attempts;
        if (balancer && balancer->s->max_attempts_set && !max_attempts)
            max_attempts = balancer->s->max_attempts;
        /* firstly, try a proxy, unless a NoProxy directive is active */
        if (!direct_connect) {
            for (i = 0; i < proxies->nelts; i++) {
@@ -1150,6 +1153,7 @@ static void * create_proxy_config(apr_pool_t *p, server_rec *s)
    ps->forward = NULL;
    ps->reverse = NULL;
    ps->domain = NULL;
    ps->id = apr_psprintf(p, "%pp", ps->noproxies);
    ps->viaopt = via_off; /* initially backward compatible with 1.3.1 */
    ps->viaopt_set = 0; /* 0 means default */
    ps->req = 0;
@@ -1188,6 +1192,7 @@ static void * merge_proxy_config(apr_pool_t *p, void *basev, void *overridesv)
    ps->reverse = overrides->reverse ? overrides->reverse : base->reverse;

    ps->domain = (overrides->domain == NULL) ? base->domain : overrides->domain;
    ps->id = (overrides->id == NULL) ? base->id : overrides->id;
    ps->viaopt = (overrides->viaopt_set == 0) ? base->viaopt : overrides->viaopt;
    ps->viaopt_set = overrides->viaopt_set || base->viaopt_set;
    ps->req = (overrides->req_set == 0) ? base->req : overrides->req;
@@ -1466,7 +1471,7 @@ static const char *
    if (ap_proxy_valid_balancer_name(r, 9)) {
        proxy_balancer *balancer = ap_proxy_get_balancer(cmd->pool, conf, r);
        if (!balancer) {
            const char *err = ap_proxy_define_balancer(cmd->pool, &balancer, conf, r);
            const char *err = ap_proxy_define_balancer(cmd->pool, &balancer, conf, r, 0);
            if (err)
                return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL);
        }
@@ -1481,7 +1486,7 @@ static const char *
        proxy_worker *worker = ap_proxy_get_worker(cmd->temp_pool, NULL, conf, r);
        int reuse = 0;
        if (!worker) {
            const char *err = ap_proxy_define_worker(cmd->pool, &worker, NULL, conf, r);
            const char *err = ap_proxy_define_worker(cmd->pool, &worker, NULL, conf, r, 0);
            if (err)
                return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL);

@@ -1901,7 +1906,7 @@ static const char *add_member(cmd_parms *cmd, void *dummy, const char *arg)
    /* Try to find the balancer */
    balancer = ap_proxy_get_balancer(cmd->temp_pool, conf, path);
    if (!balancer) {
        err = ap_proxy_define_balancer(cmd->pool, &balancer, conf, path);
        err = ap_proxy_define_balancer(cmd->pool, &balancer, conf, path, 0);
        if (err)
            return apr_pstrcat(cmd->temp_pool, "BalancerMember ", err, NULL);
    }
@@ -1912,7 +1917,7 @@ static const char *add_member(cmd_parms *cmd, void *dummy, const char *arg)
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
                     "Defining worker '%s' for balancer '%s'",
                     name, balancer->name);
        if ((err = ap_proxy_define_worker(cmd->pool, &worker, balancer, conf, name)) != NULL)
        if ((err = ap_proxy_define_worker(cmd->pool, &worker, balancer, conf, name, 0)) != NULL)
            return apr_pstrcat(cmd->temp_pool, "BalancerMember ", err, NULL);
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
                     "Defined worker '%s' for balancer '%s'",
@@ -1979,7 +1984,7 @@ static const char *
        balancer = ap_proxy_get_balancer(cmd->pool, conf, name);
        if (!balancer) {
            if (in_proxy_section) {
                err = ap_proxy_define_balancer(cmd->pool, &balancer, conf, name);
                err = ap_proxy_define_balancer(cmd->pool, &balancer, conf, name, 0);
                if (err)
                    return apr_pstrcat(cmd->temp_pool, "ProxySet ",
                                       err, NULL);
@@ -1994,7 +1999,7 @@ static const char *
        if (!worker) {
            if (in_proxy_section) {
                err = ap_proxy_define_worker(cmd->pool, &worker, NULL,
                                             conf, name);
                                             conf, name, 0);
                if (err)
                    return apr_pstrcat(cmd->temp_pool, "ProxySet ",
                                       err, NULL);
@@ -2128,7 +2133,7 @@ static const char *proxysection(cmd_parms *cmd, void *mconfig, const char *arg)
            balancer = ap_proxy_get_balancer(cmd->pool, sconf, conf->p);
            if (!balancer) {
                err = ap_proxy_define_balancer(cmd->pool, &balancer,
                                               sconf, conf->p);
                                               sconf, conf->p, 0);
                if (err)
                    return apr_pstrcat(cmd->temp_pool, thiscmd->name,
                                       " ", err, NULL);
@@ -2139,7 +2144,7 @@ static const char *proxysection(cmd_parms *cmd, void *mconfig, const char *arg)
                                         conf->p);
            if (!worker) {
                err = ap_proxy_define_worker(cmd->pool, &worker, NULL,
                                          sconf, conf->p);
                                          sconf, conf->p, 0);
                if (err)
                    return apr_pstrcat(cmd->temp_pool, thiscmd->name,
                                       " ", err, NULL);
@@ -2322,20 +2327,20 @@ static int proxy_status_hook(request_rec *r, int flags)
        ap_rputs("\n\n<table border=\"0\"><tr>"
                 "<th>SSes</th><th>Timeout</th><th>Method</th>"
                 "</tr>\n<tr>", r);
        if (balancer->sticky) {
            if (strcmp(balancer->sticky, balancer->sticky_path)) {
                ap_rvputs(r, "<td>", balancer->sticky, " | ",
                          balancer->sticky_path, NULL);
        if (*balancer->s->sticky) {
            if (strcmp(balancer->s->sticky, balancer->s->sticky_path)) {
                ap_rvputs(r, "<td>", balancer->s->sticky, " | ",
                          balancer->s->sticky_path, NULL);
            }
            else {
                ap_rvputs(r, "<td>", balancer->sticky, NULL);
                ap_rvputs(r, "<td>", balancer->s->sticky, NULL);
            }
        }
        else {
            ap_rputs("<td> - ", r);
        }
        ap_rprintf(r, "</td><td>%" APR_TIME_T_FMT "</td>",
                   apr_time_sec(balancer->timeout));
                   apr_time_sec(balancer->s->timeout));
        ap_rprintf(r, "<td>%s</td>\n",
                   balancer->lbmethod->name);
        ap_rputs("</table>\n", r);
@@ -2416,7 +2421,7 @@ static void child_init(apr_pool_t *p, server_rec *s)
        /* Create and initialize forward worker if defined */
        if (conf->req_set && conf->req) {
            proxy_worker *forward;
            ap_proxy_define_worker(p, &forward, NULL, NULL, "http://www.apache.org");
            ap_proxy_define_worker(p, &forward, NULL, NULL, "http://www.apache.org", 0);
            conf->forward = forward;
            PROXY_STRNCPY(conf->forward->s->name,     "proxy:forward");
            PROXY_STRNCPY(conf->forward->s->hostname, "*");
@@ -2430,7 +2435,7 @@ static void child_init(apr_pool_t *p, server_rec *s)
            ap_proxy_initialize_worker(conf->forward, s, conf->pool);
        }
        if (!reverse) {
            ap_proxy_define_worker(p, &reverse, NULL, NULL, "http://www.apache.org");
            ap_proxy_define_worker(p, &reverse, NULL, NULL, "http://www.apache.org", 0);
            PROXY_STRNCPY(reverse->s->name,     "proxy:reverse");
            PROXY_STRNCPY(reverse->s->hostname, "*");
            PROXY_STRNCPY(reverse->s->scheme,   "*");
+54 −16
Changes for modules/proxy/mod_proxy.h: 54 added lines, 16 removed lines.
Original line number Diff line number Diff line
@@ -135,6 +135,7 @@ typedef struct {
    proxy_worker       *forward;    /* forward proxy worker */
    proxy_worker       *reverse;    /* reverse "module-driven" proxy worker */
    const char *domain;     /* domain name to use in absence of a domain name in the request */
    const char *id;
    apr_pool_t *pool;       /* Pool used for allocating this struct */
    int req;                /* true if proxy requests are enabled */
    enum {
@@ -159,6 +160,7 @@ typedef struct {
    } proxy_status;             /* Status display options */
    apr_sockaddr_t *source_address;
    apr_global_mutex_t  *mutex; /* global lock (needed??) */
    ap_slotmem_instance_t *slot;  /* balancers shm data - runtime */

    int req_set:1;
    int viaopt_set:1;
@@ -276,9 +278,12 @@ PROXY_WORKER_DISABLED | PROXY_WORKER_STOPPED | PROXY_WORKER_IN_ERROR )

/* default worker retry timeout in seconds */
#define PROXY_WORKER_DEFAULT_RETRY    60

/* Some max char string sizes, for shm fields */
#define PROXY_WORKER_MAX_SCHEME_SIZE    16
#define PROXY_WORKER_MAX_ROUTE_SIZE     64
#define PROXY_WORKER_MAX_NAME_SIZE      96
#define PROXY_BALANCER_MAX_STICKY_SIZE  64

#define PROXY_STRNCPY(dst, src) apr_cpystrn((dst), (src), sizeof(dst))

@@ -306,6 +311,7 @@ typedef struct {
        flush_on,
        flush_auto
    } flush_packets;           /* control AJP flushing */
    apr_time_t      updated;    /* timestamp of last update */
    apr_time_t      error_time; /* time of the last error */
    apr_interval_time_t ttl;    /* maximum amount of time in seconds a connection
                                 * may be available while exceeding the soft limit */
@@ -334,13 +340,13 @@ typedef struct {
    unsigned int     io_buffer_size_set:1;
    unsigned int     keepalive_set:1;
    unsigned int     disablereuse_set:1;
    unsigned int     was_malloced:1;
} proxy_worker_shared;

#define ALIGNED_PROXY_WORKER_SHARED_SIZE (APR_ALIGN_DEFAULT(sizeof(proxy_worker_shared)))

/* Worker configuration */
struct proxy_worker {
    int             index;      /* shm array index */
    unsigned int    hash;       /* hash of worker name */
    proxy_conn_pool     *cp;    /* Connection pool to use */
    proxy_worker_shared   *s;   /* Shared data */
@@ -356,29 +362,35 @@ struct proxy_worker {
 */
#define PROXY_FLUSH_WAIT 10000

typedef struct {
    char      sticky_path[PROXY_BALANCER_MAX_STICKY_SIZE];     /* URL sticky session identifier */
    char      sticky[PROXY_BALANCER_MAX_STICKY_SIZE];          /* sticky session identifier */
    char nonce[APR_UUID_FORMATTED_LENGTH + 1];
    apr_interval_time_t timeout;  /* Timeout for waiting on free connection */
    apr_time_t      updated;    /* timestamp of last update */
    int             max_attempts;     /* Number of attempts before failing */
    int             index;      /* shm array index */
    int             sticky_force:1;   /* Disable failover for sticky sessions */
    int             scolonsep:1;      /* true if ';' seps sticky session paths */
    int             max_attempts_set:1;
    unsigned int     was_malloced:1;
} proxy_balancer_shared;

#define ALIGNED_PROXY_BALANCER_SHARED_SIZE (APR_ALIGN_DEFAULT(sizeof(proxy_balancer_shared)))

struct proxy_balancer {
    apr_array_header_t *workers;  /* initially configured workers */
    apr_array_header_t *errstatuses;  /* statuses to force members into error */
    ap_slotmem_instance_t *slot;  /* worker shm data - runtime */
    proxy_balancer_method *lbmethod;
    int growth;                   /* number of post-config workers can added */
    int max_workers;              /* maximum number of allowed workers */
    const char *name;             /* name of the load balancer */
    const char *sname;            /* filesystem safe balancer name */
    apr_interval_time_t timeout;  /* Timeout for waiting on free connection */
    const char *lbprovider;       /* name of the lbmethod provider to use */
    proxy_balancer_method *lbmethod;

    const char      *sticky_path;     /* URL sticky session identifier */
    apr_array_header_t *errstatuses;  /* statuses to force members into error */
    const char      *sticky;          /* sticky session identifier */
    int             max_attempts;     /* Number of attempts before failing */

    apr_time_t      updated;    /* timestamp of last update */
    char nonce[APR_UUID_FORMATTED_LENGTH + 1];
    apr_global_mutex_t  *mutex; /* global lock for updating lb params */
    void            *context;   /* general purpose storage */
    int             sticky_force:1;   /* Disable failover for sticky sessions */
    int             scolonsep:1;      /* true if ';' seps sticky session paths */
    int             max_attempts_set:1;
    proxy_balancer_shared *s;   /* Shared data */
};

struct proxy_balancer_method {
@@ -537,13 +549,15 @@ PROXY_DECLARE(proxy_worker *) ap_proxy_get_worker(apr_pool_t *p,
 * @param balancer  the balancer that the worker belongs to
 * @param conf      current proxy server configuration
 * @param url       url containing worker name
 * @param do_malloc true if shared struct should be malloced
 * @return          error message or NULL if successful (*worker is new worker)
 */
PROXY_DECLARE(char *) ap_proxy_define_worker(apr_pool_t *p,
                                             proxy_worker **worker,
                                             proxy_balancer *balancer,
                                             proxy_server_conf *conf,
                                                   const char *url);
                                             const char *url,
                                             int do_malloc);

/**
 * Share a defined proxy worker via shm
@@ -591,12 +605,36 @@ PROXY_DECLARE(proxy_balancer *) ap_proxy_get_balancer(apr_pool_t *p,
 * @param balancer the new balancer
 * @param conf   current proxy server configuration
 * @param url    url containing balancer name
 * @param do_malloc true if shared struct should be malloced
 * @return       error message or NULL if successfull
 */
PROXY_DECLARE(char *) ap_proxy_define_balancer(apr_pool_t *p,
                                               proxy_balancer **balancer,
                                               proxy_server_conf *conf,
                                                    const char *url);
                                               const char *url,
                                               int do_malloc);

/**
 * Share a defined proxy balancer via shm
 * @param balancer  balancer to be shared
 * @param shm       location of shared info
 * @param i         index into shm
 * @return          APR_SUCCESS or error code
 */
PROXY_DECLARE(apr_status_t) ap_proxy_share_balancer(proxy_balancer *balancer,
                                                    proxy_balancer_shared *shm,
                                                    int i);

/**
 * Initialize the balancer as needed
 * @param balancer balancer to initialize
 * @param s        current server record
 * @param p        memory pool used for mutex and connection pool
 * @return         APR_SUCCESS or error code
 */
PROXY_DECLARE(apr_status_t) ap_proxy_initialize_balancer(proxy_balancer *balancer,
                                                       server_rec *s,
                                                       apr_pool_t *p);

/**
 * Get the most suitable worker and/or balancer for the request
+80 −37

File changed.

Preview size limit exceeded, changes collapsed.

+63 −36
Changes for modules/proxy/proxy_util.c: 63 added lines, 36 removed lines.
Original line number Diff line number Diff line
@@ -1328,11 +1328,14 @@ PROXY_DECLARE(proxy_balancer *) ap_proxy_get_balancer(apr_pool_t *p,
PROXY_DECLARE(char *) ap_proxy_define_balancer(apr_pool_t *p,
                                               proxy_balancer **balancer,
                                               proxy_server_conf *conf,
                                                     const char *url)
                                               const char *url,
                                               int do_malloc)
{
    char *c, *q, *uri = apr_pstrdup(p, url);
    char nonce[APR_UUID_FORMATTED_LENGTH + 1];
    proxy_balancer_method *lbmethod;
    apr_uuid_t uuid;
    proxy_balancer_shared *bshared;
    char *c, *q, *uri = apr_pstrdup(p, url);

    /* We should never get here without a valid BALANCER_PREFIX... */

@@ -1357,33 +1360,55 @@ PROXY_DECLARE(char *) ap_proxy_define_balancer(apr_pool_t *p,
    }

    (*balancer)->name = uri;
    (*balancer)->lbmethod = lbmethod;
    (*balancer)->workers = apr_array_make(p, 5, sizeof(proxy_worker *));
    (*balancer)->updated = apr_time_now();
    (*balancer)->mutex = NULL;

    if (do_malloc)
        bshared = malloc(sizeof(proxy_balancer_shared));
    else
        bshared = apr_palloc(p, sizeof(proxy_balancer_shared));
    
    memset(bshared, 0, sizeof(proxy_balancer_shared));
    
    (*balancer)->lbmethod = lbmethod;
    bshared->updated = apr_time_now();
    bshared->was_malloced = (do_malloc != 0);

    /* Retrieve a UUID and store the nonce for the lifetime of
     * the process. */
    apr_uuid_get(&uuid);
    apr_uuid_format((*balancer)->nonce, &uuid);
    apr_uuid_format(nonce, &uuid);
    PROXY_STRNCPY(bshared->nonce, nonce);    
    
    (*balancer)->s = bshared;

    return NULL;
}

#if 0
/*
 * Create an already defined balancer and free up memory.
 * Placeholder for when we make +/- of balancers runtime as well
 */
PROXY_DECLARE(void) ap_proxy_share_balancer(TODO)
PROXY_DECLARE(apr_status_t) ap_proxy_share_balancer(proxy_balancer *balancer,
                                                    proxy_balancer_shared *shm,
                                                    int i)
{
    if (!shm || !balancer->s)
        return APR_EINVAL;

    memcpy(shm, balancer->s, sizeof(proxy_balancer_shared));
    if (balancer->s->was_malloced)
        free(balancer->s);
    balancer->s = shm;
    balancer->s->index = i;
    return APR_SUCCESS;
}

PROXY_DECLARE(void) ap_proxy_initialize_balancer(TODO)
PROXY_DECLARE(apr_status_t) ap_proxy_initialize_balancer(proxy_balancer *balancer, server_rec *s, apr_pool_t *p)
{
    apr_status_t rv = APR_SUCCESS;
    return rv;
}

#endif

/*
 * CONNECTION related...
 */
@@ -1655,11 +1680,12 @@ PROXY_DECLARE(char *) ap_proxy_define_worker(apr_pool_t *p,
                                             proxy_worker **worker,
                                             proxy_balancer *balancer,
                                             proxy_server_conf *conf,
                                                   const char *url)
                                             const char *url,
                                             int do_malloc)
{
    int rv;
    apr_uri_t uri;
    proxy_worker_shared *wstatus;
    proxy_worker_shared *wshared;

    rv = apr_uri_parse(p, url, &uri);

@@ -1697,30 +1723,31 @@ PROXY_DECLARE(char *) ap_proxy_define_worker(apr_pool_t *p,
    /* right here we just want to tuck away the worker info.
     * if called during config, we don't have shm setup yet,
     * so just note the info for later. */
#if 0
    wstatus = malloc(sizeof(proxy_worker_shared));  /* will be freed ap_proxy_share_worker */
#else
    wstatus = apr_palloc(p, sizeof(proxy_worker_shared));
#endif
    memset(wstatus, 0, sizeof(proxy_worker_shared));

    PROXY_STRNCPY(wstatus->name, apr_uri_unparse(p, &uri, APR_URI_UNP_REVEALPASSWORD));
    PROXY_STRNCPY(wstatus->scheme, uri.scheme);
    PROXY_STRNCPY(wstatus->hostname, uri.hostname);
    wstatus->port = uri.port;
    wstatus->flush_packets = flush_off;
    wstatus->flush_wait = PROXY_FLUSH_WAIT;
    wstatus->is_address_reusable = 1;
    wstatus->lbfactor = 1;
    wstatus->smax = -1;
    wstatus->hash = ap_proxy_hashfunc(wstatus->name, PROXY_HASHFUNC_DEFAULT);

    (*worker)->hash = wstatus->hash;
    if (do_malloc)
        wshared = malloc(sizeof(proxy_worker_shared));  /* will be freed ap_proxy_share_worker */
    else
        wshared = apr_palloc(p, sizeof(proxy_worker_shared));

    memset(wshared, 0, sizeof(proxy_worker_shared));

    PROXY_STRNCPY(wshared->name, apr_uri_unparse(p, &uri, APR_URI_UNP_REVEALPASSWORD));
    PROXY_STRNCPY(wshared->scheme, uri.scheme);
    PROXY_STRNCPY(wshared->hostname, uri.hostname);
    wshared->port = uri.port;
    wshared->flush_packets = flush_off;
    wshared->flush_wait = PROXY_FLUSH_WAIT;
    wshared->is_address_reusable = 1;
    wshared->lbfactor = 1;
    wshared->smax = -1;
    wshared->hash = ap_proxy_hashfunc(wshared->name, PROXY_HASHFUNC_DEFAULT);
    wshared->was_malloced = (do_malloc != 0);

    (*worker)->hash = wshared->hash;
    (*worker)->context = NULL;
    (*worker)->cp = NULL;
    (*worker)->mutex = NULL;
    (*worker)->balancer = balancer;
    (*worker)->s = wstatus;
    (*worker)->s = wshared;

    return NULL;
}
@@ -1728,15 +1755,15 @@ PROXY_DECLARE(char *) ap_proxy_define_worker(apr_pool_t *p,
/*
 * Create an already defined worker and free up memory
 */
PROXY_DECLARE(apr_status_t) ap_proxy_share_worker(proxy_worker *worker, proxy_worker_shared *shm, int i)
PROXY_DECLARE(apr_status_t) ap_proxy_share_worker(proxy_worker *worker, proxy_worker_shared *shm,
                                                  int i)
{
    if (!shm || !worker->s)
        return APR_EINVAL;

    memcpy(shm, worker->s, sizeof(proxy_worker_shared));
#if 0
    if (worker->s->was_malloced)
        free(worker->s); /* was malloced in ap_proxy_define_worker */
#endif
    worker->s = shm;
    worker->s->index = i;
    return APR_SUCCESS;