Author: rhuijben Date: Tue Nov 24 12:32:01 2015 New Revision: 1716122 URL: http://svn.apache.org/viewvc?rev=1716122&view=rev Log: Extend the config support to include listeners as well. Rename the create functions to make it clear they create a new config instance.
* config_store.c (conn_key_for_listener): New function. (serf__config_store_get_config): Split into... (serf__config_store_create_ctx_config): ... this and... (serf__config_store_create_conn_config): ... this function. (serf__config_store_get_client_config): Rename to... (serf__config_store_create_client_config): ... this. (serf__config_store_create_listener_config): New function. * context.c (serf_context_create_ex): Update caller. * incoming.c (serf_incoming_create2): Update caller. (serf_listener_create): Allocate listener in its own pool. Initialize config. * outgoing.c (serf_connection_create2): Update caller. * serf_private.h (serf__config_store_get_config): Rename to... (serf__config_store_create_conn_config): ... this. (serf__config_store_get_client_config): Rename to... (serf__config_store_create_client_config): ... this. (serf__config_store_create_listener_config, serf__config_store_create_ctx_config): New function. * test/test_internal.c (test_config_store_per_context, test_config_store_per_connection_different_host, test_config_store_per_connection_same_host, test_config_store_error_handling, test_config_store_remove_objects): Update caller. Modified: serf/trunk/config_store.c serf/trunk/context.c serf/trunk/incoming.c serf/trunk/outgoing.c serf/trunk/serf_private.h serf/trunk/test/test_internal.c Modified: serf/trunk/config_store.c URL: http://svn.apache.org/viewvc/serf/trunk/config_store.c?rev=1716122&r1=1716121&r2=1716122&view=diff ============================================================================== --- serf/trunk/config_store.c (original) +++ serf/trunk/config_store.c Tue Nov 24 12:32:01 2015 @@ -117,13 +117,18 @@ static const char * conn_key_for_client( return apr_psprintf(pool, "%pp", incoming); } +/* Defines the key to use for per connection settings */ +static const char * conn_key_for_listener(serf_listener_t *listener, + apr_pool_t *pool) +{ + /* Key needs to be unique per connection, so stringify its pointer value */ + return apr_psprintf(pool, "%pp", listener); +} + -/* TODO: when will this be released? Related config to a specific lifecyle: - connection or context */ -apr_status_t serf__config_store_get_config(serf_context_t *ctx, - serf_connection_t *conn, - serf_config_t **config, - apr_pool_t *out_pool) +apr_status_t serf__config_store_create_ctx_config(serf_context_t *ctx, + serf_config_t **config, + apr_pool_t *out_pool) { serf__config_store_t *config_store = &ctx->config_store; @@ -131,90 +136,138 @@ apr_status_t serf__config_store_get_conf cfg->ctx_pool = ctx->pool; cfg->per_context = config_store->global_per_context; - if (conn) { - const char *host_key, *conn_key; - serf__config_hdr_t *per_conn, *per_host; - apr_pool_t *tmp_pool; - apr_status_t status; - - cfg->conn_pool = conn->pool; - - if ((status = apr_pool_create(&tmp_pool, out_pool)) != APR_SUCCESS) - return status; - - /* Find the config values for this connection, create empty structure - if needed */ - conn_key = conn_key_for_conn(conn, tmp_pool); - per_conn = apr_hash_get(config_store->global_per_conn, conn_key, - APR_HASH_KEY_STRING); - if (!per_conn) { - per_conn = create_config_hdr(conn->pool); - apr_hash_set(config_store->global_per_conn, - apr_pstrdup(conn->pool, conn_key), - APR_HASH_KEY_STRING, per_conn); - } - cfg->per_conn = per_conn; - - /* Find the config values for this host, create empty structure - if needed */ - host_key = host_key_for_conn(conn, tmp_pool); - per_host = apr_hash_get(config_store->global_per_host, - host_key, - APR_HASH_KEY_STRING); - if (!per_host) { - per_host = create_config_hdr(config_store->pool); - apr_hash_set(config_store->global_per_host, - apr_pstrdup(config_store->pool, host_key), - APR_HASH_KEY_STRING, per_host); - } - cfg->per_host = per_host; + *config = cfg; + return APR_SUCCESS; +} + +apr_status_t serf__config_store_create_conn_config(serf_connection_t *conn, + serf_config_t **config, + apr_pool_t *out_pool) +{ + serf__config_store_t *config_store = &conn->ctx->config_store; + const char *host_key, *conn_key; + serf__config_hdr_t *per_conn, *per_host; + apr_pool_t *tmp_pool; + apr_status_t status; + + serf_config_t *cfg = apr_pcalloc(out_pool, sizeof(serf_config_t)); + cfg->ctx_pool = conn->ctx->pool; + cfg->per_context = config_store->global_per_context; + + cfg->conn_pool = conn->pool; + + if ((status = apr_pool_create(&tmp_pool, out_pool)) != APR_SUCCESS) + return status; - apr_pool_destroy(tmp_pool); + /* Find the config values for this connection, create empty structure + if needed */ + conn_key = conn_key_for_conn(conn, tmp_pool); + per_conn = apr_hash_get(config_store->global_per_conn, conn_key, + APR_HASH_KEY_STRING); + if (!per_conn) { + per_conn = create_config_hdr(conn->pool); + apr_hash_set(config_store->global_per_conn, + apr_pstrdup(conn->pool, conn_key), + APR_HASH_KEY_STRING, per_conn); } + cfg->per_conn = per_conn; + + /* Find the config values for this host, create empty structure + if needed */ + host_key = host_key_for_conn(conn, tmp_pool); + per_host = apr_hash_get(config_store->global_per_host, + host_key, + APR_HASH_KEY_STRING); + if (!per_host) { + per_host = create_config_hdr(config_store->pool); + apr_hash_set(config_store->global_per_host, + apr_pstrdup(config_store->pool, host_key), + APR_HASH_KEY_STRING, per_host); + } + cfg->per_host = per_host; + + apr_pool_destroy(tmp_pool); *config = cfg; return APR_SUCCESS; } -apr_status_t serf__config_store_get_client_config(serf_context_t *ctx, - serf_incoming_t *client, - serf_config_t **config, - apr_pool_t *out_pool) +apr_status_t serf__config_store_create_client_config(serf_incoming_t *client, + serf_config_t **config, + apr_pool_t *out_pool) { - serf__config_store_t *config_store = &ctx->config_store; + serf__config_store_t *config_store = &client->ctx->config_store; + const char *client_key; + serf__config_hdr_t *per_conn; + apr_pool_t *tmp_pool; + apr_status_t status; serf_config_t *cfg = apr_pcalloc(out_pool, sizeof(serf_config_t)); - cfg->ctx_pool = ctx->pool; + cfg->ctx_pool = client->ctx->pool; cfg->per_context = config_store->global_per_context; - if (client) { - const char *client_key; - serf__config_hdr_t *per_conn; - apr_pool_t *tmp_pool; - apr_status_t status; - cfg->conn_pool = client->pool; + cfg->conn_pool = client->pool; - if ((status = apr_pool_create(&tmp_pool, out_pool)) != APR_SUCCESS) - return status; + if ((status = apr_pool_create(&tmp_pool, out_pool)) != APR_SUCCESS) + return status; - /* Find the config values for this connection, create empty structure - if needed */ - client_key = conn_key_for_client(client, tmp_pool); - per_conn = apr_hash_get(config_store->global_per_conn, client_key, - APR_HASH_KEY_STRING); - if (!per_conn) { - per_conn = create_config_hdr(client->pool); - apr_hash_set(config_store->global_per_conn, - apr_pstrdup(client->pool, client_key), - APR_HASH_KEY_STRING, per_conn); - } - cfg->per_conn = per_conn; - cfg->per_host = NULL; + /* Find the config values for this connection, create empty structure + if needed */ + client_key = conn_key_for_client(client, tmp_pool); + per_conn = apr_hash_get(config_store->global_per_conn, client_key, + APR_HASH_KEY_STRING); + if (!per_conn) { + per_conn = create_config_hdr(client->pool); + apr_hash_set(config_store->global_per_conn, + apr_pstrdup(client->pool, client_key), + APR_HASH_KEY_STRING, per_conn); + } + cfg->per_conn = per_conn; + cfg->per_host = NULL; + + apr_pool_destroy(tmp_pool); + + *config = cfg; + + return APR_SUCCESS; +} + +apr_status_t serf__config_store_create_listener_config(serf_listener_t *listener, + serf_config_t **config, + apr_pool_t *out_pool) +{ + serf__config_store_t *config_store = &listener->ctx->config_store; + const char *client_key; + serf__config_hdr_t *per_conn; + apr_pool_t *tmp_pool; + apr_status_t status; + + serf_config_t *cfg = apr_pcalloc(out_pool, sizeof(serf_config_t)); + cfg->ctx_pool = listener->ctx->pool; + cfg->per_context = config_store->global_per_context; + + cfg->conn_pool = listener->pool; - apr_pool_destroy(tmp_pool); + if ((status = apr_pool_create(&tmp_pool, out_pool)) != APR_SUCCESS) + return status; + + /* Find the config values for this connection, create empty structure + if needed */ + client_key = conn_key_for_listener(listener, tmp_pool); + per_conn = apr_hash_get(config_store->global_per_conn, client_key, + APR_HASH_KEY_STRING); + if (!per_conn) { + per_conn = create_config_hdr(listener->pool); + apr_hash_set(config_store->global_per_conn, + apr_pstrdup(listener->pool, client_key), + APR_HASH_KEY_STRING, per_conn); } + cfg->per_conn = per_conn; + cfg->per_host = NULL; + + apr_pool_destroy(tmp_pool); *config = cfg; Modified: serf/trunk/context.c URL: http://svn.apache.org/viewvc/serf/trunk/context.c?rev=1716122&r1=1716121&r2=1716122&view=diff ============================================================================== --- serf/trunk/context.c (original) +++ serf/trunk/context.c Tue Nov 24 12:32:01 2015 @@ -195,7 +195,7 @@ serf_context_t *serf_context_create_ex( /* Assume returned status is APR_SUCCESS */ serf__config_store_init(ctx); - serf__config_store_get_config(ctx, NULL, &ctx->config, ctx->pool); + serf__config_store_create_ctx_config(ctx, &ctx->config, ctx->pool); serf__log_init(ctx); Modified: serf/trunk/incoming.c URL: http://svn.apache.org/viewvc/serf/trunk/incoming.c?rev=1716122&r1=1716121&r2=1716122&view=diff ============================================================================== --- serf/trunk/incoming.c (original) +++ serf/trunk/incoming.c Tue Nov 24 12:32:01 2015 @@ -570,8 +570,7 @@ apr_status_t serf_incoming_create2( ic->closed_baton = closed_baton; /* Store the connection specific info in the configuration store */ - status = serf__config_store_get_client_config(ctx, ic, &config, - client_pool); + status = serf__config_store_create_client_config(ic, &config, client_pool); if (status) return status; @@ -617,7 +616,15 @@ apr_status_t serf_listener_create( { apr_sockaddr_t *sa; apr_status_t rv; - serf_listener_t *l = apr_palloc(pool, sizeof(*l)); + apr_pool_t *listener_pool; + serf_listener_t *l; + serf_config_t *config; + + apr_pool_create(&listener_pool, pool); + + l = apr_palloc(pool, sizeof(*l)); + + l->pool = listener_pool; l->ctx = ctx; l->io.type = SERF_IO_LISTENER; @@ -628,8 +635,6 @@ apr_status_t serf_listener_create( l->accept_func = accept; l->accept_baton = accept_baton; - apr_pool_create(&l->pool, pool); - rv = apr_sockaddr_info_get(&sa, host, APR_UNSPEC, port, 0, l->pool); if (rv) { apr_pool_destroy(l->pool); @@ -676,6 +681,13 @@ apr_status_t serf_listener_create( return rv; } + /* Store the connection specific info in the configuration store */ + rv = serf__config_store_create_listener_config(l, &config, l->pool); + if (rv) + return rv; + + l->config = config; + *listener = l; return APR_SUCCESS; Modified: serf/trunk/outgoing.c URL: http://svn.apache.org/viewvc/serf/trunk/outgoing.c?rev=1716122&r1=1716121&r2=1716122&view=diff ============================================================================== --- serf/trunk/outgoing.c (original) +++ serf/trunk/outgoing.c Tue Nov 24 12:32:01 2015 @@ -1314,7 +1314,7 @@ apr_status_t serf_connection_create2( } /* Store the connection specific info in the configuration store */ - status = serf__config_store_get_config(ctx, c, &config, pool); + status = serf__config_store_create_conn_config(c, &config, pool); if (status) return status; c->config = config; Modified: serf/trunk/serf_private.h URL: http://svn.apache.org/viewvc/serf/trunk/serf_private.h?rev=1716122&r1=1716121&r2=1716122&view=diff ============================================================================== --- serf/trunk/serf_private.h (original) +++ serf/trunk/serf_private.h Tue Nov 24 12:32:01 2015 @@ -324,28 +324,34 @@ typedef struct serf__config_store_t { /* Initializes the data structures used by the configuration store */ apr_status_t serf__config_store_init(serf_context_t *ctx); -/* Returns a config object, which is a read/write view on the configuration +/* Create a config object, which is a read/write view on the configuration store. This view is limited to: - all per context configuration - per host configuration (host as defined in CONN) - per connection configuration - If CONN is NULL, only the per context configuration will be available. - The host and connection entries will be created in the configuration store when not existing already. The config object will be allocated in OUT_POOL. The config object's lifecycle cannot extend beyond that of the serf context! */ -apr_status_t serf__config_store_get_config(serf_context_t *ctx, - serf_connection_t *conn, - serf_config_t **config, - apr_pool_t *out_pool); +apr_status_t serf__config_store_create_conn_config(serf_connection_t *conn, + serf_config_t **config, + apr_pool_t *out_pool); /* Same thing, but for incoming connections */ -apr_status_t serf__config_store_get_client_config(serf_context_t *ctx, - serf_incoming_t *client, +apr_status_t serf__config_store_create_client_config(serf_incoming_t *client, + serf_config_t **config, + apr_pool_t *out_pool); + +/* Same thing, but for listeners */ +apr_status_t serf__config_store_create_listener_config(serf_listener_t *listener, + serf_config_t **config, + apr_pool_t *out_pool); + +/* Same thing, but for the context itself */ +apr_status_t serf__config_store_create_ctx_config(serf_context_t *ctx, serf_config_t **config, apr_pool_t *out_pool); @@ -420,6 +426,7 @@ struct serf_listener_t { apr_pollfd_t desc; void *accept_baton; serf_accept_client_t accept_func; + serf_config_t *config; }; struct serf_incoming_t { Modified: serf/trunk/test/test_internal.c URL: http://svn.apache.org/viewvc/serf/trunk/test/test_internal.c?rev=1716122&r1=1716121&r2=1716122&view=diff ============================================================================== --- serf/trunk/test/test_internal.c (original) +++ serf/trunk/test/test_internal.c Tue Nov 24 12:32:01 2015 @@ -54,7 +54,7 @@ static void test_config_store_per_contex /* We don't have a serf connection yet, so only the per context config should be available to read and write */ CuAssertIntEquals(tc, APR_SUCCESS, - serf__config_store_get_config(ctx, NULL, &cfg, tb->pool)); + serf__config_store_create_ctx_config(ctx, &cfg, tb->pool)); CuAssertPtrEquals(tc, NULL, cfg->per_conn); CuAssertPtrEquals(tc, NULL, cfg->per_host); CuAssertPtrNotNull(tc, cfg->per_context); @@ -119,15 +119,15 @@ static void test_config_store_per_connec /* Test 1: This should return a config object with per_context, per_host and per_connection hash_table's initialized. */ CuAssertIntEquals(tc, APR_SUCCESS, - serf__config_store_get_config(ctx, conn1, &cfg1, - tb->pool)); + serf__config_store_create_conn_config(conn1, &cfg1, + tb->pool)); CuAssertPtrNotNull(tc, cfg1->per_context); CuAssertPtrNotNull(tc, cfg1->per_host); CuAssertPtrNotNull(tc, cfg1->per_conn); /* Get a config object for the other connection also. */ CuAssertIntEquals(tc, APR_SUCCESS, - serf__config_store_get_config(ctx, conn2, &cfg2, - tb->pool)); + serf__config_store_create_conn_config(conn2, &cfg2, + tb->pool)); /* Test 2: Get a non-existing per connection key, value should be NULL */ CuAssertIntEquals(tc, APR_SUCCESS, @@ -182,15 +182,15 @@ static void test_config_store_per_connec /* Test 1: This should return a config object with per_context, per_host and per_connection hash_table's initialized. */ CuAssertIntEquals(tc, APR_SUCCESS, - serf__config_store_get_config(ctx, conn1, &cfg1, - tb->pool)); + serf__config_store_create_conn_config(conn1, &cfg1, + tb->pool)); CuAssertPtrNotNull(tc, cfg1->per_context); CuAssertPtrNotNull(tc, cfg1->per_host); CuAssertPtrNotNull(tc, cfg1->per_conn); /* Get a config object for the other connection also. */ CuAssertIntEquals(tc, APR_SUCCESS, - serf__config_store_get_config(ctx, conn2, &cfg2, - tb->pool)); + serf__config_store_create_conn_config(conn2, &cfg2, + tb->pool)); /* Test 2: Get a non-existing per connection key, value should be NULL */ CuAssertIntEquals(tc, APR_SUCCESS, @@ -236,7 +236,8 @@ static void test_config_store_error_hand serf_context_t *ctx = serf_context_create(tb->pool); CuAssertIntEquals(tc, APR_SUCCESS, - serf__config_store_get_config(ctx, NULL, &cfg, tb->pool)); + serf__config_store_create_ctx_config(ctx, &cfg, + tb->pool)); /* Config only has per-context keys, check for no crashes when getting per-connection and per-host keys. */ @@ -281,7 +282,8 @@ static void test_config_store_remove_obj conn_closed, NULL, tb->pool); CuAssertIntEquals(tc, APR_SUCCESS, - serf__config_store_get_config(ctx, conn, &cfg, tb->pool)); + serf__config_store_create_conn_config(conn, &cfg, + tb->pool)); /* Add and remove a key per-context */ CuAssertIntEquals(tc, APR_SUCCESS,