From 42cd69a8a00ba347b50ad0f153a3d5b27442f68a Mon Sep 17 00:00:00 2001 From: Susan Hinrichs Date: Wed, 22 Aug 2018 23:50:54 +0000 Subject: [PATCH] Fix lost pending_actions causing actions on stale objects. --- iocore/net/P_UnixNetVConnection.h | 7 +++++++ proxy/http/HttpSM.cc | 29 +++++++++++++++++++++-------- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/iocore/net/P_UnixNetVConnection.h b/iocore/net/P_UnixNetVConnection.h index a00229049ba..8b81738473b 100644 --- a/iocore/net/P_UnixNetVConnection.h +++ b/iocore/net/P_UnixNetVConnection.h @@ -154,6 +154,7 @@ class UnixNetVConnection : public NetVConnection void cancel_active_timeout() override; void cancel_inactivity_timeout() override; void set_action(Continuation *c) override; + const Action *get_action() const; void add_to_keep_alive_queue() override; void remove_from_keep_alive_queue() override; bool add_to_active_queue() override; @@ -435,6 +436,12 @@ UnixNetVConnection::set_action(Continuation *c) action_ = c; } +TS_INLINE const Action * +UnixNetVConnection::get_action() const +{ + return &action_; +} + // declarations for local use (within the net module) void write_to_net(NetHandler *nh, UnixNetVConnection *vc, EThread *thread); diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc index d41a076cbe1..ec61b9dc98a 100644 --- a/proxy/http/HttpSM.cc +++ b/proxy/http/HttpSM.cc @@ -1729,15 +1729,16 @@ HttpSM::state_http_server_open(int event, void *data) { SMDebug("http_track", "entered inside state_http_server_open"); STATE_ENTER(&HttpSM::state_http_server_open, event); - // TODO decide whether to uncomment after finish testing redirect - // ink_assert(server_entry == NULL); - pending_action = nullptr; + ink_release_assert(event == EVENT_INTERVAL || event == NET_EVENT_OPEN || event == NET_EVENT_OPEN_FAILED || pending_action == nullptr); + if (event != NET_EVENT_OPEN) { + pending_action = nullptr; + } milestones[TS_MILESTONE_SERVER_CONNECT_END] = Thread::get_hrtime(); HttpServerSession *session; NetVConnection *netvc = nullptr; switch (event) { - case NET_EVENT_OPEN: + case NET_EVENT_OPEN: { session = (TS_SERVER_SESSION_SHARING_POOL_THREAD == t_state.http_config_param->server_session_sharing_pool) ? THREAD_ALLOC_INIT(httpServerSessionAllocator, mutex->thread_holding) : httpServerSessionAllocator.alloc(); @@ -1746,7 +1747,12 @@ HttpSM::state_http_server_open(int event, void *data) netvc = static_cast(data); session->attach_hostname(t_state.current.server->name); - session->new_connection(netvc); + UnixNetVConnection *vc = static_cast(data); + ink_release_assert(pending_action == nullptr || pending_action == vc->get_action()); + pending_action = nullptr; + + session->new_connection(vc); + session->state = HSS_ACTIVE; ats_ip_copy(&t_state.server_info.src_addr, netvc->get_local_addr()); @@ -1777,7 +1783,7 @@ HttpSM::state_http_server_open(int event, void *data) handle_http_server_open(); } return 0; - + } case VC_EVENT_WRITE_READY: case VC_EVENT_WRITE_COMPLETE: // Update the time out to the regular connection timeout. @@ -1826,6 +1832,9 @@ HttpSM::state_http_server_open(int event, void *data) HTTP_INCREMENT_DYN_STAT(http_origin_connections_throttled_stat); send_origin_throttled_response(); } else { + // Go ahead and release the failed server session. Since it didn't receive a response, the release logic will + // see that it didn't get a valid response and it will close it rather than returning it to the server session pool + release_server_session(); call_transact_and_set_next_state(HttpTransact::HandleResponse); } return 0; @@ -2312,6 +2321,7 @@ HttpSM::state_hostdb_reverse_lookup(int event, void *data) int HttpSM::state_mark_os_down(int event, void *data) { + STATE_ENTER(&HttpSM::state_mark_os_down, event); HostDBInfo *mark_down = nullptr; if (event == EVENT_HOST_DB_LOOKUP && data) { @@ -5377,7 +5387,7 @@ HttpSM::handle_http_server_open() (t_state.hdr_info.request_content_length > 0 || t_state.client_info.transfer_encoding == HttpTransact::CHUNKED_ENCODING) && do_post_transform_open()) { do_setup_post_tunnel(HTTP_TRANSFORM_VC); - } else { + } else if (server_session != nullptr) { setup_server_send_request_api(); } } @@ -6837,7 +6847,10 @@ HttpSM::kill_this() // then the value of kill_this_async_done has changed so // we must check it again if (kill_this_async_done == true) { - ink_assert(pending_action == nullptr); + if (pending_action) { + pending_action->cancel(); + pending_action = nullptr; + } if (t_state.http_config_param->enable_http_stats) { update_stats(); }