summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbojan <bojan@13f79535-47bb-0310-9956-ffa450edef68>2009-02-21 21:40:07 +0000
committerbojan <bojan@13f79535-47bb-0310-9956-ffa450edef68>2009-02-21 21:40:07 +0000
commit932bed61bd2b90b431d50b57f20785fc862bfa89 (patch)
tree133ac90282be0ca82ce691bc59c1986bd3f95700
parent8c242c96535ade1b9b52c570982d94f33bde4488 (diff)
downloadlibapr-util-932bed61bd2b90b431d50b57f20785fc862bfa89.tar.gz
Fix apr_memcache_multgetp memory corruption and incorrect error handling.
Patch by Sami Tolvanen <sami.tolvanen mywot.com>. PR 46588. Sync CHANGES file from 1.4.x. git-svn-id: http://svn.apache.org/repos/asf/apr/apr-util/trunk@746592 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--CHANGES12
-rw-r--r--memcache/apr_memcache.c46
2 files changed, 43 insertions, 15 deletions
diff --git a/CHANGES b/CHANGES
index e9450f1a..3c9cc786 100644
--- a/CHANGES
+++ b/CHANGES
@@ -3,6 +3,18 @@ Changes with APR-util 2.0.0
Changes with APR-util 1.4.0
+ *) Fix apr_memcache_multgetp memory corruption and incorrect error
+ handling. PR 46588 [Sami Tolvanen <sami.tolvanen mywot.com>]
+
+ *) Fix memcache memory leak with persistent connections.
+ PR 46482 [Sami Tolvanen <sami.tolvanen mywot.com>]
+
+ *) Add Oracle 11 support. [Bojan Smojver]
+
+ *) apr_dbd_freetds: Avoid segfault when process is NULL.
+ Do no print diagnostics to stderr. Never allow driver to exit
+ process. [Bojan Smojver]
+
*) Do not include apr.h and apr_errno.h from system search path in
apu_errno.h. PR 46487 [Rainer Jung <rainer.jung kippdata.de>]
diff --git a/memcache/apr_memcache.c b/memcache/apr_memcache.c
index e74454af..d244d564 100644
--- a/memcache/apr_memcache.c
+++ b/memcache/apr_memcache.c
@@ -1128,7 +1128,8 @@ apr_memcache_add_multget_key(apr_pool_t *data_pool,
apr_hash_set(*values, value->key, klen, value);
}
-static void mget_conn_result(int up,
+static void mget_conn_result(int serverup,
+ int connup,
apr_status_t rv,
apr_memcache_t *mc,
apr_memcache_server_t *ms,
@@ -1140,9 +1141,16 @@ static void mget_conn_result(int up,
apr_int32_t j;
apr_memcache_value_t* value;
- if (!up) {
+ apr_hash_set(server_queries, &ms, sizeof(ms), NULL);
+
+ if (connup) {
+ ms_release_conn(ms, conn);
+ } else {
ms_bad_conn(ms, conn);
- apr_memcache_disable_server(mc, ms);
+
+ if (!serverup) {
+ apr_memcache_disable_server(mc, ms);
+ }
}
for (j = 1; j < server_query->query_vec_count ; j+=2) {
@@ -1155,10 +1163,6 @@ static void mget_conn_result(int up,
}
}
}
-
- ms_release_conn(ms, conn);
-
- apr_hash_set(server_queries, &ms, sizeof(ms), NULL);
}
APU_DECLARE(apr_status_t)
@@ -1265,6 +1269,18 @@ apr_memcache_multgetp(apr_memcache_t *mc,
rv = apr_pollset_create(&pollset, apr_hash_count(server_queries), temp_pool, 0);
if (rv != APR_SUCCESS) {
+ query_hash_index = apr_hash_first(temp_pool, server_queries);
+
+ while (query_hash_index) {
+ void *v;
+ apr_hash_this(query_hash_index, NULL, NULL, &v);
+ server_query = v;
+ query_hash_index = apr_hash_next(query_hash_index);
+
+ mget_conn_result(TRUE, TRUE, rv, mc, server_query->ms, server_query->conn,
+ server_query, values, server_queries);
+ }
+
return rv;
}
@@ -1287,7 +1303,7 @@ apr_memcache_multgetp(apr_memcache_t *mc,
}
if (rv != APR_SUCCESS) {
- mget_conn_result(FALSE, rv, mc, ms, conn,
+ mget_conn_result(FALSE, FALSE, rv, mc, ms, conn,
server_query, values, server_queries);
continue;
}
@@ -1319,7 +1335,7 @@ apr_memcache_multgetp(apr_memcache_t *mc,
if (rv != APR_SUCCESS) {
apr_pollset_remove (pollset, &activefds[i]);
- mget_conn_result(FALSE, rv, mc, ms, conn,
+ mget_conn_result(FALSE, FALSE, rv, mc, ms, conn,
server_query, values, server_queries);
queries_sent--;
continue;
@@ -1349,7 +1365,7 @@ apr_memcache_multgetp(apr_memcache_t *mc,
if (value) {
- if (len > 0) {
+ if (len >= 0) {
apr_bucket_brigade *bbb;
apr_bucket *e;
@@ -1358,7 +1374,7 @@ apr_memcache_multgetp(apr_memcache_t *mc,
if (rv != APR_SUCCESS) {
apr_pollset_remove (pollset, &activefds[i]);
- mget_conn_result(FALSE, rv, mc, ms, conn,
+ mget_conn_result(FALSE, FALSE, rv, mc, ms, conn,
server_query, values, server_queries);
queries_sent--;
continue;
@@ -1370,7 +1386,7 @@ apr_memcache_multgetp(apr_memcache_t *mc,
if (rv != APR_SUCCESS) {
apr_pollset_remove (pollset, &activefds[i]);
- mget_conn_result(FALSE, rv, mc, ms, conn,
+ mget_conn_result(FALSE, FALSE, rv, mc, ms, conn,
server_query, values, server_queries);
queries_sent--;
continue;
@@ -1379,7 +1395,7 @@ apr_memcache_multgetp(apr_memcache_t *mc,
rv = apr_brigade_destroy(conn->bb);
if (rv != APR_SUCCESS) {
apr_pollset_remove (pollset, &activefds[i]);
- mget_conn_result(FALSE, rv, mc, ms, conn,
+ mget_conn_result(FALSE, FALSE, rv, mc, ms, conn,
server_query, values, server_queries);
queries_sent--;
continue;
@@ -1430,13 +1446,13 @@ apr_memcache_multgetp(apr_memcache_t *mc,
conn = server_query->conn;
ms = server_query->ms;
- mget_conn_result(TRUE, rv, mc, ms, conn,
+ mget_conn_result(TRUE, (rv == APR_SUCCESS), rv, mc, ms, conn,
server_query, values, server_queries);
continue;
}
- apr_pool_clear(temp_pool);
apr_pollset_destroy(pollset);
+ apr_pool_clear(temp_pool);
return APR_SUCCESS;
}