From 191be1b5d660deff622276ba7dc05c19e820c4e3 Mon Sep 17 00:00:00 2001 From: Eric Covener Date: Sat, 21 Jun 2014 13:03:19 +0000 Subject: [PATCH] missed a case in r1538490: PR56639 Always NULL c->sbh before putting a connection back in a pollset or queue. We can't NULL c->sbh at the bottom of process_socket() after putting a socket back on the event_pollset or having it go into lingering close, because the listener or a worker thread could A) continue on the connection or B) free and allocate the same conn_rec pointer before we get to the bottom of process_socket(). Submitted By: Edward Lu Committed By: covener git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1604350 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 4 ++++ server/mpm/event/event.c | 20 +++++--------------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/CHANGES b/CHANGES index 1f693908cf..5dac72c8ce 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.0 + *) event MPM: Fix possible crashes (third party modules accessing c->sbh) + or occasional missed mod_status updates for some initial requests + on a connection under load. PR 56639.[Edward Lu ] + *) mod_deflate: Don't fail when flushing inflated data to the user-agent and that coincides with the end of stream ("Zlib error flushing inflate buffer"). PR 56196. [Christoph Fausak ] diff --git a/server/mpm/event/event.c b/server/mpm/event/event.c index eab34b8bd9..9980f5606e 100644 --- a/server/mpm/event/event.c +++ b/server/mpm/event/event.c @@ -845,6 +845,7 @@ static int start_lingering_close_common(event_conn_state_t *cs) cs->pub.sense == CONN_SENSE_WANT_WRITE ? APR_POLLOUT : APR_POLLIN) | APR_POLLHUP | APR_POLLERR; cs->pub.sense = CONN_SENSE_DEFAULT; + cs->c->sbh = NULL; rv = apr_pollset_add(event_pollset, &cs->pfd); apr_thread_mutex_unlock(timeout_mutex); if (rv != APR_SUCCESS && !APR_STATUS_IS_EEXIST(rv)) { @@ -1130,11 +1131,8 @@ read_request: } if (cs->pub.state == CONN_STATE_LINGER) { - if (!start_lingering_close_blocking(cs)) { - c->sbh = NULL; - notify_suspend(cs); - return; - } + start_lingering_close_blocking(cs); + notify_suspend(cs); } else if (cs->pub.state == CONN_STATE_CHECK_REQUEST_LINE_READABLE) { /* It greatly simplifies the logic to use a single timeout value here @@ -1162,21 +1160,13 @@ read_request: "process_socket: apr_pollset_add failure"); AP_DEBUG_ASSERT(rc == APR_SUCCESS); } - return; } else if (cs->pub.state == CONN_STATE_SUSPENDED) { cs->c->suspended_baton = cs; apr_atomic_inc32(&suspended_count); + c->sbh = NULL; + notify_suspend(cs); } - /* - * Prevent this connection from writing to our connection state after it - * is no longer associated with this thread. This would happen if the EOR - * bucket is destroyed from the listener thread due to a connection abort - * or timeout. - */ - c->sbh = NULL; - notify_suspend(cs); - return; } /* Put a SUSPENDED connection back into a queue. */ -- 2.50.1