to the pool we cannot longer rely on it as another thread could have leased
the connection in the meantime and might have modified it.
BUT: We only use this flag once we returned the connection to the pool.
So signal that we returned the connection to the pool by something that is
local to the thread, in this case set backend to NULL if we already have
returende the connection.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@
1052314 13f79535-47bb-0310-9956-
ffa450edef68
* 20101113.1 (2.3.9-dev) Add ap_set_flag_slot_char()
* 20101113.2 (2.3.9-dev) Add ap_expr_exec_re()
* 20101204.0 (2.3.10-dev) Add _t to ap_expr's typedef names
* 20101113.1 (2.3.9-dev) Add ap_set_flag_slot_char()
* 20101113.2 (2.3.9-dev) Add ap_expr_exec_re()
* 20101204.0 (2.3.10-dev) Add _t to ap_expr's typedef names
+ * 20101223.0 (2.3.11-dev) Remove cleaned from proxy_conn_rec.
*/
#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
#ifndef MODULE_MAGIC_NUMBER_MAJOR
*/
#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
#ifndef MODULE_MAGIC_NUMBER_MAJOR
-#define MODULE_MAGIC_NUMBER_MAJOR 20101204
+#define MODULE_MAGIC_NUMBER_MAJOR 20101223
#endif
#define MODULE_MAGIC_NUMBER_MINOR 0 /* 0...n */
#endif
#define MODULE_MAGIC_NUMBER_MINOR 0 /* 0...n */
#if APR_HAS_THREADS
int inreslist:1; /* connection in apr_reslist? */
#endif
#if APR_HAS_THREADS
int inreslist:1; /* connection in apr_reslist? */
#endif
- int cleaned:1; /* connection cleaned? */
} proxy_conn_rec;
typedef struct {
} proxy_conn_rec;
typedef struct {
static
apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r,
static
apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r,
- proxy_conn_rec *backend,
+ proxy_conn_rec **backend_ptr,
proxy_worker *worker,
proxy_server_conf *conf,
char *server_portstr) {
proxy_worker *worker,
proxy_server_conf *conf,
char *server_portstr) {
int proxy_status = OK;
const char *original_status_line = r->status_line;
const char *proxy_status_line = NULL;
int proxy_status = OK;
const char *original_status_line = r->status_line;
const char *proxy_status_line = NULL;
+ proxy_conn_rec *backend = *backend_ptr;
conn_rec *origin = backend->connection;
apr_interval_time_t old_timeout = 0;
proxy_dir_conf *dconf;
conn_rec *origin = backend->connection;
apr_interval_time_t old_timeout = 0;
proxy_dir_conf *dconf;
*/
ap_proxy_release_connection(backend->worker->scheme,
backend, r->server);
*/
ap_proxy_release_connection(backend->worker->scheme,
backend, r->server);
+ /* Ensure that the backend is not reused */
+ backend_ptr = NULL;
if (ap_pass_brigade(r->output_filters, pass_bb) != APR_SUCCESS
|| c->aborted) {
/* Ack! Phbtt! Die! User aborted! */
if (ap_pass_brigade(r->output_filters, pass_bb) != APR_SUCCESS
|| c->aborted) {
/* Ack! Phbtt! Die! User aborted! */
- if (!backend->cleaned) {
+ /* Only close backend if we haven't got all from the
+ * backend. Furthermore if backend_ptr is NULL it is no
+ * longer save to fiddle around with backend as it might
+ * be already in use by another thread.
+ */
+ if (backend_ptr) {
backend->close = 1; /* this causes socket close below */
}
finish = TRUE;
backend->close = 1; /* this causes socket close below */
}
finish = TRUE;
*/
ap_proxy_release_connection(backend->worker->scheme,
backend, r->server);
*/
ap_proxy_release_connection(backend->worker->scheme,
backend, r->server);
/* Pass EOS bucket down the filter chain. */
e = apr_bucket_eos_create(c->bucket_alloc);
/* Pass EOS bucket down the filter chain. */
e = apr_bucket_eos_create(c->bucket_alloc);
}
/* Step Five: Receive the Response... Fall thru to cleanup */
}
/* Step Five: Receive the Response... Fall thru to cleanup */
- status = ap_proxy_http_process_response(p, r, backend, worker,
+ status = ap_proxy_http_process_response(p, r, &backend, worker,
conf, server_portstr);
break;
conf, server_portstr);
break;
/* Step Six: Clean Up */
cleanup:
if (backend) {
/* Step Six: Clean Up */
cleanup:
if (backend) {
- if ((status != OK) && (!backend->cleaned))
backend->close = 1;
ap_proxy_http_cleanup(proxy_function, r, backend);
}
backend->close = 1;
ap_proxy_http_cleanup(proxy_function, r, backend);
}
#if APR_HAS_THREADS
(*conn)->inreslist = 0;
#endif
#if APR_HAS_THREADS
(*conn)->inreslist = 0;
#endif
proxy_conn_rec *conn,
server_rec *s)
{
proxy_conn_rec *conn,
server_rec *s)
{
- if (!conn->cleaned) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
"proxy: %s: has released connection for (%s)",
proxy_function, conn->worker->hostname);
"proxy: %s: has released connection for (%s)",
proxy_function, conn->worker->hostname);
- connection_cleanup(conn);
- conn->cleaned = 1;
- }
+ connection_cleanup(conn);