You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by ok...@apache.org on 2017/10/13 02:12:17 UTC
[trafficserver] branch master updated: Optimize: If failed on
migrateToCurrentThread,
put the server session back to global server session pool
This is an automated email from the ASF dual-hosted git repository.
oknet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new c776c66 Optimize: If failed on migrateToCurrentThread, put the server session back to global server session pool
c776c66 is described below
commit c776c6677b0c005dd511945ae023a14f8f6b0bc3
Author: Oknet Xu <xu...@skyguard.com.cn>
AuthorDate: Fri Sep 1 22:18:54 2017 +0800
Optimize: If failed on migrateToCurrentThread, put the server session back to global server session pool
---
iocore/net/UnixNetVConnection.cc | 74 +++++++++++++++++++++++++++-------------
proxy/http/HttpSessionManager.cc | 24 ++++++-------
2 files changed, 61 insertions(+), 37 deletions(-)
diff --git a/iocore/net/UnixNetVConnection.cc b/iocore/net/UnixNetVConnection.cc
index a4c7769..0e97ffa 100644
--- a/iocore/net/UnixNetVConnection.cc
+++ b/iocore/net/UnixNetVConnection.cc
@@ -1244,6 +1244,7 @@ UnixNetVConnection::populate(Connection &con_in, Continuation *c, void *arg)
}
if (h->startIO(this) < 0) {
+ con_in.move(this->con);
Debug("iocore_net", "populate : Failed to add to epoll list");
return EVENT_ERROR;
}
@@ -1430,44 +1431,71 @@ UnixNetVConnection::migrateToCurrentThread(Continuation *cont, EThread *t)
return this;
}
- Connection hold_con;
- hold_con.move(this->con);
- SSLNetVConnection *sslvc = dynamic_cast<SSLNetVConnection *>(this);
-
- SSL *save_ssl = (sslvc) ? sslvc->ssl : nullptr;
- if (save_ssl) {
- SSLNetVCDetach(sslvc->ssl);
- sslvc->ssl = nullptr;
+ // Lock the NetHandler first in order to put the new NetVC into NetHandler and InactivityCop.
+ // It is safe and no performance issue to get the mutex lock for a NetHandler of current ethread.
+ SCOPED_MUTEX_LOCK(lock, client_nh->mutex, t);
+
+ // Try to get the mutex lock for NetHandler of this NetVC
+ MUTEX_TRY_LOCK(lock_src, this->nh->mutex, t);
+ if (lock_src.is_locked()) {
+ // Deattach this NetVC from original NetHandler & InactivityCop.
+ this->nh->stopCop(this);
+ this->nh->stopIO(this);
+ // Put this NetVC into current NetHandler & InactivityCop.
+ this->thread = t;
+ client_nh->startIO(this);
+ client_nh->startCop(this);
+ // Move this NetVC to current EThread Successfully.
+ return this;
}
- // Do_io_close will signal the VC to be freed on the original thread
- // Since we moved the con context, the fd will not be closed
- // Go ahead and remove the fd from the original thread's epoll structure, so it is not
- // processed on two threads simultaneously
- this->ep.stop();
- this->do_io_close();
+ // Failed to get the mutex lock for original NetHandler.
+ // Try to migrate it by create a new NetVC and then move con.fd and ssl ctx.
+ SSLNetVConnection *sslvc = dynamic_cast<SSLNetVConnection *>(this);
+ SSL *save_ssl = (sslvc) ? sslvc->ssl : nullptr;
+
+ UnixNetVConnection *ret_vc = nullptr;
// Create new VC:
if (save_ssl) {
SSLNetVConnection *sslvc = static_cast<SSLNetVConnection *>(sslNetProcessor.allocate_vc(t));
- if (sslvc->populate(hold_con, cont, save_ssl) != EVENT_DONE) {
- sslvc->do_io_close();
- sslvc = nullptr;
+ if (sslvc->populate(this->con, cont, save_ssl) != EVENT_DONE) {
+ sslvc->free(t);
+ sslvc = nullptr;
+ ret_vc = this;
} else {
sslvc->set_context(get_context());
+ ret_vc = dynamic_cast<UnixNetVConnection *>(sslvc);
}
- return sslvc;
- // Update the SSL fields
} else {
UnixNetVConnection *netvc = static_cast<UnixNetVConnection *>(netProcessor.allocate_vc(t));
- if (netvc->populate(hold_con, cont, save_ssl) != EVENT_DONE) {
- netvc->do_io_close();
- netvc = nullptr;
+ if (netvc->populate(this->con, cont, save_ssl) != EVENT_DONE) {
+ netvc->free(t);
+ netvc = nullptr;
+ ret_vc = this;
} else {
netvc->set_context(get_context());
+ ret_vc = netvc;
}
- return netvc;
}
+
+ // clear con.fd and ssl ctx from this NetVC since a new NetVC is created.
+ if (ret_vc != this) {
+ if (save_ssl) {
+ SSLNetVCDetach(sslvc->ssl);
+ sslvc->ssl = nullptr;
+ }
+ ink_assert(this->con.fd == NO_FD);
+
+ // Do_io_close will signal the VC to be freed on the original thread
+ // Since we moved the con context, the fd will not be closed
+ // Go ahead and remove the fd from the original thread's epoll structure, so it is not
+ // processed on two threads simultaneously
+ this->ep.stop();
+ this->do_io_close();
+ }
+
+ return ret_vc;
}
void
diff --git a/proxy/http/HttpSessionManager.cc b/proxy/http/HttpSessionManager.cc
index 1e4334a..49450f2 100644
--- a/proxy/http/HttpSessionManager.cc
+++ b/proxy/http/HttpSessionManager.cc
@@ -326,21 +326,17 @@ HttpSessionManager::acquire_session(Continuation * /* cont ATS_UNUSED */, sockad
UnixNetVConnection *server_vc = dynamic_cast<UnixNetVConnection *>(to_return->get_netvc());
if (server_vc) {
UnixNetVConnection *new_vc = server_vc->migrateToCurrentThread(sm, ethread);
- // The VC moved, free up the original one
- if (new_vc != server_vc) {
- ink_assert(new_vc == nullptr || new_vc->nh != nullptr);
- if (!new_vc) {
- // Close out to_return, we were't able to get a connection
- to_return->do_io_close();
- to_return = nullptr;
- retval = HSM_NOT_FOUND;
- } else {
- // Keep things from timing out on us
- new_vc->set_inactivity_timeout(new_vc->get_inactivity_timeout());
- to_return->set_netvc(new_vc);
- }
+ if (new_vc->thread != ethread) {
+ // Failed to migrate, put it back to global session pool
+ m_g_pool->releaseSession(to_return);
+ to_return = nullptr;
+ retval = HSM_NOT_FOUND;
+ } else if (new_vc != server_vc) {
+ // The VC migrated, keep things from timing out on us
+ new_vc->set_inactivity_timeout(new_vc->get_inactivity_timeout());
+ to_return->set_netvc(new_vc);
} else {
- // Keep things from timing out on us
+ // The VC moved, keep things from timing out on us
server_vc->set_inactivity_timeout(server_vc->get_inactivity_timeout());
}
}
--
To stop receiving notification emails like this one, please contact
['"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>'].