Author: zwoop
Date: Thu Sep 15 16:10:32 2011
New Revision: 1171160
URL: http://svn.apache.org/viewvc?rev=1171160&view=rev
Log:
TS-924 More efficient sharing of origin connections.
This also overloads the config for shared connections as follows:
# 0 - Never
# 1 - Share, with a single global connection pool
# 2 - Share, with a connection pool per worker thread
CONFIG proxy.config.http.share_server_sessions INT 1
This option is now per-request (remap or plugin) overridable.
Modified:
trafficserver/traffic/trunk/iocore/eventsystem/I_EThread.h
trafficserver/traffic/trunk/iocore/eventsystem/UnixEThread.cc
trafficserver/traffic/trunk/proxy/InkAPI.cc
trafficserver/traffic/trunk/proxy/InkAPITest.cc
trafficserver/traffic/trunk/proxy/api/ts/ts.h.in
trafficserver/traffic/trunk/proxy/config/records.config.default.in
trafficserver/traffic/trunk/proxy/http/HttpClientSession.cc
trafficserver/traffic/trunk/proxy/http/HttpClientSession.h
trafficserver/traffic/trunk/proxy/http/HttpConfig.cc
trafficserver/traffic/trunk/proxy/http/HttpConfig.h
trafficserver/traffic/trunk/proxy/http/HttpSM.cc
trafficserver/traffic/trunk/proxy/http/HttpServerSession.cc
trafficserver/traffic/trunk/proxy/http/HttpServerSession.h
trafficserver/traffic/trunk/proxy/http/HttpSessionManager.cc
trafficserver/traffic/trunk/proxy/http/HttpSessionManager.h
Modified: trafficserver/traffic/trunk/iocore/eventsystem/I_EThread.h
URL:
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/iocore/eventsystem/I_EThread.h?rev=1171160&r1=1171159&r2=1171160&view=diff
==============================================================================
--- trafficserver/traffic/trunk/iocore/eventsystem/I_EThread.h (original)
+++ trafficserver/traffic/trunk/iocore/eventsystem/I_EThread.h Thu Sep 15
16:10:32 2011
@@ -42,23 +42,24 @@
/** Maximum number of accept events per thread. */
#define MAX_ACCEPT_EVENTS 20
-struct UDPNetHandler;
struct DiskHandler;
-struct LogConfiguration;
-struct LogEventForwarder;
struct EventIO;
class SessionBucket;
-class NetHandler;
class Event;
class Continuation;
-class IOBufferData;
-class IOBufferBlock;
-enum ThreadType
-{ REGULAR = 0, MONITOR, DEDICATED };
-enum teThreadType
-{ keAsyncThread = 0, keBoundThread, keSpawnThread };
+enum ThreadType {
+ REGULAR = 0,
+ MONITOR,
+ DEDICATED
+};
+
+enum teThreadType {
+ keAsyncThread = 0,
+ keBoundThread,
+ keSpawnThread
+};
/**
Event System specific type of thread.
@@ -90,10 +91,9 @@ enum teThreadType
@see Event
*/
-class EThread:public Thread
+class EThread: public Thread
{
public:
-
/*-------------------------------------------------------*\
| Common Interface |
\*-------------------------------------------------------*/
@@ -115,8 +115,8 @@ public:
of this callback.
*/
- Event * schedule_imm(Continuation * c, int callback_event = EVENT_IMMEDIATE,
void *cookie = NULL);
- Event * schedule_imm_signal(Continuation * c, int callback_event =
EVENT_IMMEDIATE, void *cookie = NULL);
+ Event *schedule_imm(Continuation *c, int callback_event = EVENT_IMMEDIATE,
void *cookie = NULL);
+ Event *schedule_imm_signal(Continuation *c, int callback_event =
EVENT_IMMEDIATE, void *cookie = NULL);
/**
Schedules the continuation on this EThread to receive an event
@@ -137,7 +137,7 @@ public:
of this callback.
*/
- Event *schedule_at(Continuation * c,
+ Event *schedule_at(Continuation *c,
ink_hrtime atimeout_at, int callback_event =
EVENT_INTERVAL, void *cookie = NULL);
/**
@@ -158,7 +158,7 @@ public:
of this callback.
*/
- Event *schedule_in(Continuation * c,
+ Event *schedule_in(Continuation *c,
ink_hrtime atimeout_in, int callback_event =
EVENT_INTERVAL, void *cookie = NULL);
/**
@@ -180,7 +180,7 @@ public:
of this callback.
*/
- Event *schedule_every(Continuation * c, ink_hrtime aperiod, int
callback_event = EVENT_INTERVAL, void *cookie = NULL);
+ Event *schedule_every(Continuation *c, ink_hrtime aperiod, int
callback_event = EVENT_INTERVAL, void *cookie = NULL);
/**
Schedules the continuation on this EThread to receive an event
@@ -198,7 +198,7 @@ public:
of this callback.
*/
- Event *schedule_imm_local(Continuation * c, int callback_event =
EVENT_IMMEDIATE, void *cookie = NULL);
+ Event *schedule_imm_local(Continuation *c, int callback_event =
EVENT_IMMEDIATE, void *cookie = NULL);
/**
Schedules the continuation on this EThread to receive an event
@@ -219,7 +219,7 @@ public:
of this callback.
*/
- Event *schedule_at_local(Continuation * c,
+ Event *schedule_at_local(Continuation *c,
ink_hrtime atimeout_at, int callback_event =
EVENT_INTERVAL, void *cookie = NULL);
/**
@@ -241,7 +241,7 @@ public:
of this callback.
*/
- Event *schedule_in_local(Continuation * c,
+ Event *schedule_in_local(Continuation *c,
ink_hrtime atimeout_in, int callback_event =
EVENT_INTERVAL, void *cookie = NULL);
/**
@@ -262,22 +262,20 @@ public:
of this callback.
*/
- Event *schedule_every_local(Continuation * c,
+ Event *schedule_every_local(Continuation *c,
ink_hrtime aperiod, int callback_event =
EVENT_INTERVAL, void *cookie = NULL);
/* private */
- Event *schedule_local(Event * e);
+ Event *schedule_local(Event *e);
InkRand generator;
ProxyAllocator eventAllocator;
ProxyAllocator netVCAllocator;
ProxyAllocator sslNetVCAllocator;
- ProxyAllocator inkioNetVCAllocator;
ProxyAllocator httpClientSessionAllocator;
ProxyAllocator httpServerSessionAllocator;
ProxyAllocator cacheVConnectionAllocator;
- ProxyAllocator newCacheVConnectionAllocator;
ProxyAllocator openDirEntryAllocator;
ProxyAllocator ramCacheCLFUSEntryAllocator;
ProxyAllocator ramCacheLRUEntryAllocator;
@@ -287,32 +285,26 @@ public:
ProxyAllocator ioBufAllocator[DEFAULT_BUFFER_SIZES];
private:
-
// prevent unauthorized copies (Not implemented)
- EThread(const EThread &);
- EThread & operator =(const EThread &);
+ EThread(const EThread &);
+ EThread & operator =(const EThread &);
/*-------------------------------------------------------*\
| UNIX Interface |
\*-------------------------------------------------------*/
public:
-
- EThread();
- EThread(ThreadType att, int anid);
- EThread(ThreadType att, Event *e, ink_sem *sem);
- virtual ~ EThread();
+ EThread();
+ EThread(ThreadType att, int anid);
+ EThread(ThreadType att, Event *e, ink_sem *sem);
+ virtual ~EThread();
Event *schedule_spawn(Continuation *cont);
-
Event *schedule(Event *e, bool fast_signal = false);
/** Block of memory to allocate thread specific data e.g. stat system
arrays. */
char thread_private[PER_THREAD_DATA];
- // private data for UDP net processor
- //UDPNetHandler *udpNetHandler;
-
/** Private Data for the Disk Processor. */
DiskHandler *diskHandler;
@@ -338,8 +330,8 @@ public:
// Private Interface
void execute();
- void process_event(Event * e, int calling_code);
- void free_event(Event * e);
+ void process_event(Event *e, int calling_code);
+ void free_event(Event *e);
void (*signal_hook)(EThread *);
#if TS_HAS_EVENTFD
@@ -352,6 +344,8 @@ public:
ThreadType tt;
Event *oneevent; // For dedicated event thread
ink_sem *eventsem; // For dedicated event thread
+
+ SessionBucket* l1_hash;
};
/**
@@ -362,8 +356,9 @@ public:
class ink_dummy_for_new
{
};
+
inline void *operator
-new(size_t, ink_dummy_for_new * p)
+new(size_t, ink_dummy_for_new *p)
{
return (void *) p;
}
Modified: trafficserver/traffic/trunk/iocore/eventsystem/UnixEThread.cc
URL:
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/iocore/eventsystem/UnixEThread.cc?rev=1171160&r1=1171159&r2=1171160&view=diff
==============================================================================
--- trafficserver/traffic/trunk/iocore/eventsystem/UnixEThread.cc (original)
+++ trafficserver/traffic/trunk/iocore/eventsystem/UnixEThread.cc Thu Sep 15
16:10:32 2011
@@ -61,7 +61,8 @@ EThread::EThread(ThreadType att, int ani
event_types(0),
signal_hook(0),
tt(att),
- eventsem(NULL)
+ eventsem(NULL),
+ l1_hash(NULL)
{
ethreads_to_be_signalled = (EThread **)ats_malloc(MAX_EVENT_THREADS *
sizeof(EThread *));
memset((char *) ethreads_to_be_signalled, 0, MAX_EVENT_THREADS *
sizeof(EThread *));
@@ -107,8 +108,9 @@ EThread::~EThread()
{
if (n_ethreads_to_be_signalled > 0)
flush_signals(this);
- if (ethreads_to_be_signalled)
- ats_free(ethreads_to_be_signalled);
+ ats_free(ethreads_to_be_signalled);
+ // TODO: This can't be deleted ....
+ // delete[]l1_hash;
}
bool
Modified: trafficserver/traffic/trunk/proxy/InkAPI.cc
URL:
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/InkAPI.cc?rev=1171160&r1=1171159&r2=1171160&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/InkAPI.cc (original)
+++ trafficserver/traffic/trunk/proxy/InkAPI.cc Thu Sep 15 16:10:32 2011
@@ -7242,6 +7242,9 @@ _conf_to_memberp(TSOverridableConfigKey
case TS_CONFIG_HTTP_KEEP_ALIVE_POST_OUT:
ret = &sm->t_state.txn_conf->keep_alive_post_out;
break;
+ case TS_CONFIG_HTTP_SHARE_SERVER_SESSIONS:
+ ret = &sm->t_state.txn_conf->share_server_sessions;
+ break;
case TS_CONFIG_NET_SOCK_RECV_BUFFER_SIZE_OUT:
ret = &sm->t_state.txn_conf->sock_recv_buffer_size_out;
break;
@@ -7628,6 +7631,8 @@ TSHttpTxnConfigFind(const char* name, in
case 's':
if (!strncmp(name, "proxy.config.http.doc_in_cache_skip_dns", length))
cnf = TS_CONFIG_HTTP_DOC_IN_CACHE_SKIP_DNS;
+ else if (!strncmp(name, "proxy.config.http.share_server_sessions",
length))
+ cnf = TS_CONFIG_HTTP_SHARE_SERVER_SESSIONS;
break;
}
break;
Modified: trafficserver/traffic/trunk/proxy/InkAPITest.cc
URL:
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/InkAPITest.cc?rev=1171160&r1=1171159&r2=1171160&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/InkAPITest.cc (original)
+++ trafficserver/traffic/trunk/proxy/InkAPITest.cc Thu Sep 15 16:10:32 2011
@@ -7505,6 +7505,7 @@ const char *SDK_Overridable_Configs[] =
"proxy.config.http.keep_alive_enabled_in",
"proxy.config.http.keep_alive_enabled_out",
"proxy.config.http.keep_alive_post_out",
+ "proxy.config.http.share_server_sessions",
"proxy.config.net.sock_recv_buffer_size_out",
"proxy.config.net.sock_send_buffer_size_out",
"proxy.config.net.sock_option_flag_out",
Modified: trafficserver/traffic/trunk/proxy/api/ts/ts.h.in
URL:
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/api/ts/ts.h.in?rev=1171160&r1=1171159&r2=1171160&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/api/ts/ts.h.in (original)
+++ trafficserver/traffic/trunk/proxy/api/ts/ts.h.in Thu Sep 15 16:10:32 2011
@@ -494,6 +494,7 @@ extern "C"
TS_CONFIG_HTTP_KEEP_ALIVE_ENABLED_IN,
TS_CONFIG_HTTP_KEEP_ALIVE_ENABLED_OUT,
TS_CONFIG_HTTP_KEEP_ALIVE_POST_OUT,
+ TS_CONFIG_HTTP_SHARE_SERVER_SESSIONS,
TS_CONFIG_NET_SOCK_RECV_BUFFER_SIZE_OUT,
TS_CONFIG_NET_SOCK_SEND_BUFFER_SIZE_OUT,
TS_CONFIG_NET_SOCK_OPTION_FLAG_OUT,
Modified: trafficserver/traffic/trunk/proxy/config/records.config.default.in
URL:
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/config/records.config.default.in?rev=1171160&r1=1171159&r2=1171160&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/config/records.config.default.in
(original)
+++ trafficserver/traffic/trunk/proxy/config/records.config.default.in Thu Sep
15 16:10:32 2011
@@ -104,6 +104,10 @@ CONFIG proxy.config.http.chunking_enable
# 3 - if the client request is 1.1 & the server
# has returned 1.1 before
CONFIG proxy.config.http.send_http11_requests INT 1
+ # Share server connections
+ # 0 - Never
+ # 1 - Share, with a single global connection pool
+ # 2 - Share, with a connection pool per worker thread
CONFIG proxy.config.http.share_server_sessions INT 1
CONFIG proxy.config.http.origin_server_pipeline INT 1
CONFIG proxy.config.http.user_agent_pipeline INT 8
Modified: trafficserver/traffic/trunk/proxy/http/HttpClientSession.cc
URL:
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/http/HttpClientSession.cc?rev=1171160&r1=1171159&r2=1171160&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/http/HttpClientSession.cc (original)
+++ trafficserver/traffic/trunk/proxy/http/HttpClientSession.cc Thu Sep 15
16:10:32 2011
@@ -63,7 +63,7 @@ HttpClientSession::HttpClientSession()
read_buffer(NULL), current_reader(NULL), read_state(HCS_INIT),
ka_vio(NULL), slave_ka_vio(NULL),
cur_hook_id(TS_HTTP_LAST_HOOK), cur_hook(NULL),
- cur_hooks(0), backdoor_connect(false), hooks_set(0),
+ cur_hooks(0), proxy_allocated(false), backdoor_connect(false),
hooks_set(0),
m_active(false)
{
memset(user_args, 0, sizeof(user_args));
@@ -102,7 +102,10 @@ void
HttpClientSession::destroy()
{
this->cleanup();
- httpClientSessionAllocator.free(this);
+ if (proxy_allocated)
+ THREAD_FREE(this, httpClientSessionAllocator, this_ethread());
+ else
+ httpClientSessionAllocator.free(this);
}
HttpClientSession *
Modified: trafficserver/traffic/trunk/proxy/http/HttpClientSession.h
URL:
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/http/HttpClientSession.h?rev=1171160&r1=1171159&r2=1171160&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/http/HttpClientSession.h (original)
+++ trafficserver/traffic/trunk/proxy/http/HttpClientSession.h Thu Sep 15
16:10:32 2011
@@ -45,17 +45,15 @@ class HttpServerSession;
class SecurityContext;
-class HttpClientSession:public VConnection
+class HttpClientSession: public VConnection
{
public:
HttpClientSession();
void cleanup();
virtual void destroy();
-public:
static HttpClientSession *allocate();
-public:
void new_connection(NetVConnection * new_vc, bool backdoor = false);
virtual VIO *do_io_read(Continuation * c, int64_t nbytes = INT64_MAX,
MIOBuffer * buf = 0);
@@ -135,6 +133,7 @@ private:
TSHttpHookID cur_hook_id;
APIHook *cur_hook;
int cur_hooks;
+ bool proxy_allocated;
// api_hooks must not be changed directly
// Use ssn_hook_{ap,pre}pend so hooks_set is
Modified: trafficserver/traffic/trunk/proxy/http/HttpConfig.cc
URL:
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/http/HttpConfig.cc?rev=1171160&r1=1171159&r2=1171160&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/http/HttpConfig.cc (original)
+++ trafficserver/traffic/trunk/proxy/http/HttpConfig.cc Thu Sep 15 16:10:32
2011
@@ -1186,7 +1186,7 @@ HttpConfig::startup()
"proxy.config.http.session_auth_cache_keep_alive_enabled");
HttpEstablishStaticConfigLongLong(c.origin_server_pipeline,
"proxy.config.http.origin_server_pipeline");
HttpEstablishStaticConfigLongLong(c.user_agent_pipeline,
"proxy.config.http.user_agent_pipeline");
- HttpEstablishStaticConfigLongLong(c.share_server_sessions,
"proxy.config.http.share_server_sessions");
+ HttpEstablishStaticConfigByte(c.oride.share_server_sessions,
"proxy.config.http.share_server_sessions");
HttpEstablishStaticConfigByte(c.oride.keep_alive_post_out,
"proxy.config.http.keep_alive_post_out");
HttpEstablishStaticConfigLongLong(c.oride.keep_alive_no_activity_timeout_in,
@@ -1462,7 +1462,7 @@ HttpConfig::reconfigure()
params->session_auth_cache_keep_alive_enabled =
INT_TO_BOOL(m_master.session_auth_cache_keep_alive_enabled);
params->origin_server_pipeline = m_master.origin_server_pipeline;
params->user_agent_pipeline = m_master.user_agent_pipeline;
- params->share_server_sessions = INT_TO_BOOL(m_master.share_server_sessions);
+ params->oride.share_server_sessions = m_master.oride.share_server_sessions;
params->oride.keep_alive_post_out =
INT_TO_BOOL(m_master.oride.keep_alive_post_out);
params->oride.keep_alive_no_activity_timeout_in =
m_master.oride.keep_alive_no_activity_timeout_in;
Modified: trafficserver/traffic/trunk/proxy/http/HttpConfig.h
URL:
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/http/HttpConfig.h?rev=1171160&r1=1171159&r2=1171160&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/http/HttpConfig.h (original)
+++ trafficserver/traffic/trunk/proxy/http/HttpConfig.h Thu Sep 15 16:10:32 2011
@@ -402,13 +402,12 @@ struct OverridableHttpConfigParams {
: maintain_pristine_host_hdr(0), chunking_enabled(0),
negative_caching_enabled(0), negative_caching_lifetime(0),
cache_when_to_revalidate(0),
keep_alive_enabled_in(0), keep_alive_enabled_out(0),
keep_alive_post_out(0),
- server_tcp_init_cwnd(0),
+ server_tcp_init_cwnd(0), share_server_sessions(0),
sock_recv_buffer_size_out(0), sock_send_buffer_size_out(0),
sock_option_flag_out(0),
fwd_proxy_auth_to_parent(0),
anonymize_remove_from(0), anonymize_remove_referer(0),
anonymize_remove_user_agent(0),
anonymize_remove_cookie(0), anonymize_remove_client_ip(0),
anonymize_insert_client_ip(1),
append_xforwards_header(0), proxy_response_server_enabled(0),
-
insert_squid_x_forwarded_for(0), send_http11_requests(3), //
SEND_HTTP11_IF_REQUEST_11_AND_HOSTDB
cache_http(0), cache_ignore_client_no_cache(0),
cache_ignore_client_cc_max_age(1),
cache_ims_on_client_no_cache(0), cache_ignore_server_no_cache(0),
cache_responses_to_cookies(0),
@@ -455,6 +454,8 @@ struct OverridableHttpConfigParams {
MgmtByte keep_alive_post_out; // share server sessions for post
MgmtInt server_tcp_init_cwnd;
+ MgmtByte share_server_sessions;
+
///////////////////////////////////////
// origin server connection settings //
///////////////////////////////////////
@@ -644,7 +645,6 @@ public:
MgmtByte session_auth_cache_keep_alive_enabled;
MgmtInt origin_server_pipeline;
MgmtInt user_agent_pipeline;
- MgmtInt share_server_sessions;
MgmtInt transaction_active_timeout_in;
MgmtInt accept_no_activity_timeout;
MgmtInt background_fill_active_timeout;
@@ -924,7 +924,6 @@ HttpConfigParams::HttpConfigParams()
session_auth_cache_keep_alive_enabled(0),
origin_server_pipeline(0),
user_agent_pipeline(0),
- share_server_sessions(0),
transaction_active_timeout_in(0),
accept_no_activity_timeout(0),
background_fill_active_timeout(0),
Modified: trafficserver/traffic/trunk/proxy/http/HttpSM.cc
URL:
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/http/HttpSM.cc?rev=1171160&r1=1171159&r2=1171160&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/http/HttpSM.cc (original)
+++ trafficserver/traffic/trunk/proxy/http/HttpSM.cc Thu Sep 15 16:10:32 2011
@@ -1610,7 +1610,11 @@ HttpSM::state_http_server_open(int event
switch (event) {
case NET_EVENT_OPEN:
- session = THREAD_ALLOC_INIT(httpServerSessionAllocator,
mutex->thread_holding);
+ session = (2 == t_state.txn_conf->share_server_sessions) ?
+ THREAD_ALLOC_INIT(httpServerSessionAllocator, mutex->thread_holding) :
+ httpServerSessionAllocator.alloc();
+ session->share_session = t_state.txn_conf->share_server_sessions;
+
// If origin_max_connections or origin_min_keep_alive_connections is
// set then we are metering the max and or min number
// of connections per host. Set enable_origin_connection_limiting
@@ -4139,7 +4143,7 @@ HttpSM::do_http_server_open(bool raw)
// to do this but as far I can tell the code that prevented keep-alive if
// there is a request body has been removed.
- if (raw == false && t_state.http_config_param->share_server_sessions &&
+ if (raw == false && t_state.txn_conf->share_server_sessions &&
(t_state.txn_conf->keep_alive_post_out == 1 ||
t_state.hdr_info.request_content_length == 0) &&
ua_session != NULL) {
shared_result = httpSessionManager.acquire_session(this, // state
machine
@@ -4169,7 +4173,7 @@ HttpSM::do_http_server_open(bool raw)
// This bug was due to when share_server_sessions is set to 0
// and we have keep-alive, we are trying to open a new server session
// when we already have an attached server session.
- else if ((!t_state.http_config_param->share_server_sessions) && (ua_session
!= NULL)) {
+ else if ((!t_state.txn_conf->share_server_sessions) && (ua_session != NULL))
{
HttpServerSession *existing_ss = ua_session->get_server_session();
if (existing_ss) {
@@ -5059,7 +5063,7 @@ HttpSM::attach_server_session(HttpServer
server_session->mutex = this->mutex;
HTTP_INCREMENT_DYN_STAT(http_current_server_transactions_stat);
- s->server_trans_stat++;
+ ++s->server_trans_stat;
// Record the VC in our table
server_entry = vc_table.new_entry();
Modified: trafficserver/traffic/trunk/proxy/http/HttpServerSession.cc
URL:
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/http/HttpServerSession.cc?rev=1171160&r1=1171159&r2=1171160&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/http/HttpServerSession.cc (original)
+++ trafficserver/traffic/trunk/proxy/http/HttpServerSession.cc Thu Sep 15
16:10:32 2011
@@ -27,9 +27,7 @@
Description:
-
****************************************************************************/
-
#include "ink_config.h"
#include "Allocator.h"
#include "HttpServerSession.h"
@@ -39,6 +37,7 @@
static int64_t next_ss_id = (int64_t) 0;
ClassAllocator<HttpServerSession>
httpServerSessionAllocator("httpServerSessionAllocator");
+
void
HttpServerSession::destroy()
{
@@ -52,27 +51,20 @@ HttpServerSession::destroy()
}
mutex.clear();
- httpServerSessionAllocator.free(this);
-}
-
-HttpServerSession *
-HttpServerSession::allocate()
-{
- ink_assert(0);
- return NULL;
+ if (2 == share_session)
+ THREAD_FREE(this, httpServerSessionAllocator, this_ethread());
+ else
+ httpServerSessionAllocator.free(this);
}
void
-HttpServerSession::new_connection(NetVConnection * new_vc)
+HttpServerSession::new_connection(NetVConnection *new_vc)
{
ink_assert(new_vc != NULL);
server_vc = new_vc;
-#ifdef TRANSACTION_ON_A_THREAD
- mutex = new_vc->thread->mutex;
-#else
+ // Used to do e.g. mutex = new_vc->thread->mutex; when per-thread pools
enabled
mutex = new_vc->mutex;
-#endif
// Unique client session identifier.
con_id = ink_atomic_increment64((int64_t *) (&next_ss_id), 1);
@@ -99,13 +91,13 @@ HttpServerSession::new_connection(NetVCo
}
VIO *
-HttpServerSession::do_io_read(Continuation * c, int64_t nbytes, MIOBuffer *
buf)
+HttpServerSession::do_io_read(Continuation *c, int64_t nbytes, MIOBuffer *buf)
{
return server_vc->do_io_read(c, nbytes, buf);
}
VIO *
-HttpServerSession::do_io_write(Continuation * c, int64_t nbytes,
IOBufferReader * buf, bool owner)
+HttpServerSession::do_io_write(Continuation *c, int64_t nbytes, IOBufferReader
*buf, bool owner)
{
return server_vc->do_io_write(c, nbytes, buf, owner);
}
@@ -151,7 +143,7 @@ HttpServerSession::do_io_close(int alerr
}
void
-HttpServerSession::reenable(VIO * vio)
+HttpServerSession::reenable(VIO *vio)
{
server_vc->reenable(vio);
}
@@ -167,12 +159,13 @@ HttpServerSession::release()
state = HSS_KA_SHARED;
// Private sessions are never released back to the shared pool
- if (private_session || HttpConfig::m_master.share_server_sessions == 0) {
+ if (private_session || share_session == 0) {
this->do_io_close();
return;
}
HSMresult_t r = httpSessionManager.release_session(this);
+
if (r == HSM_RETRY) {
// Session could not be put in the session manager
Modified: trafficserver/traffic/trunk/proxy/http/HttpServerSession.h
URL:
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/http/HttpServerSession.h?rev=1171160&r1=1171159&r2=1171160&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/http/HttpServerSession.h (original)
+++ trafficserver/traffic/trunk/proxy/http/HttpServerSession.h Thu Sep 15
16:10:32 2011
@@ -56,7 +56,7 @@ enum HSS_State {
HSS_INIT,
HSS_ACTIVE,
HSS_KA_CLIENT_SLAVE,
- HSS_KA_SHARED
+ HSS_KA_SHARED
};
enum {
@@ -72,15 +72,14 @@ public:
server_ip(0), server_port(0), hostname_hash(),
host_hash_computed(false), con_id(0), transact_count(0),
state(HSS_INIT), to_parent_proxy(false), server_trans_stat(0),
- private_session(false),
+ private_session(false), share_session(0),
enable_origin_connection_limiting(false),
- connection_count(NULL),
- read_buffer(NULL), server_vc(NULL), magic(HTTP_SS_MAGIC_DEAD),
buf_reader(NULL)
- { }
+ connection_count(NULL), read_buffer(NULL),
+ server_vc(NULL), magic(HTTP_SS_MAGIC_DEAD), buf_reader(NULL)
+ { }
void destroy();
- static HttpServerSession *allocate();
- void new_connection(NetVConnection * new_vc);
+ void new_connection(NetVConnection *new_vc);
void reset_read_buffer(void)
{
@@ -96,14 +95,14 @@ public:
return buf_reader;
};
- virtual VIO *do_io_read(Continuation * c, int64_t nbytes = INT64_MAX,
MIOBuffer * buf = 0);
+ virtual VIO *do_io_read(Continuation *c, int64_t nbytes = INT64_MAX,
MIOBuffer *buf = 0);
- virtual VIO *do_io_write(Continuation * c = NULL, int64_t nbytes =
INT64_MAX, IOBufferReader * buf = 0, bool owner = false);
+ virtual VIO *do_io_write(Continuation *c = NULL, int64_t nbytes = INT64_MAX,
IOBufferReader *buf = 0, bool owner = false);
virtual void do_io_close(int lerrno = -1);
virtual void do_io_shutdown(ShutdownHowTo_t howto);
- virtual void reenable(VIO * vio);
+ virtual void reenable(VIO *vio);
void release();
void attach_hostname(const char *hostname);
@@ -136,7 +135,9 @@ public:
// Sessions become if authenication headers
// are sent over them
bool private_session;
- //bool www_auth_content;
+
+ // Copy of the owning SM's share_server_session setting
+ int share_session;
LINK(HttpServerSession, lru_link);
LINK(HttpServerSession, hash_link);
Modified: trafficserver/traffic/trunk/proxy/http/HttpSessionManager.cc
URL:
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/http/HttpSessionManager.cc?rev=1171160&r1=1171159&r2=1171160&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/http/HttpSessionManager.cc (original)
+++ trafficserver/traffic/trunk/proxy/http/HttpSessionManager.cc Thu Sep 15
16:10:32 2011
@@ -41,7 +41,8 @@
HttpSessionManager httpSessionManager;
-SessionBucket::SessionBucket():Continuation(NULL)
+SessionBucket::SessionBucket()
+ : Continuation(NULL)
{
SET_HANDLER(&SessionBucket::session_handler);
}
@@ -84,7 +85,6 @@ SessionBucket::session_handler(int event
while (s != NULL) {
if (s->get_netvc() == net_vc) {
-
// if there was a timeout of some kind on a keep alive connection, and
// keeping the connection alive will not keep us above the # of max
connections
// to the origin and we are below the min number of keep alive
connections to this
@@ -92,7 +92,6 @@ SessionBucket::session_handler(int event
if ((event == VC_EVENT_INACTIVITY_TIMEOUT || event ==
VC_EVENT_ACTIVE_TIMEOUT) &&
s->state == HSS_KA_SHARED &&
s->enable_origin_connection_limiting) {
-
bool connection_count_below_min =
s->connection_count->getCount(s->server_ip) <=
http_config_params->origin_min_keep_alive_connections;
if (connection_count_below_min) {
@@ -132,13 +131,6 @@ SessionBucket::session_handler(int event
return 0;
}
-HttpSessionManager::HttpSessionManager()
-{
-}
-
-HttpSessionManager::~HttpSessionManager()
-{
-}
void
HttpSessionManager::init()
@@ -171,26 +163,57 @@ HttpSessionManager::purge_keepalives()
}
}
}
+
+HSMresult_t
+_acquire_session(SessionBucket *bucket, unsigned int ip, int port, INK_MD5
&hostname_hash, HttpSM *sm)
+{
+ HttpServerSession *b;
+ HttpServerSession *to_return = NULL;
+ int l2_index = SECOND_LEVEL_HASH(ip);
+
+ ink_assert(l2_index < HSM_LEVEL2_BUCKETS);
+
+ // Check to see if an appropriate connection is in
+ // the 2nd level bucket
+ b = bucket->l2_hash[l2_index].head;
+ while (b != NULL) {
+ if (b->server_ip == ip && b->server_port == port) {
+ if (hostname_hash == b->hostname_hash) {
+ bucket->lru_list.remove(b);
+ bucket->l2_hash[l2_index].remove(b);
+ b->state = HSS_ACTIVE;
+ to_return = b;
+ Debug("http_ss", "[%" PRId64 "] [acquire session] " "return session
from shared pool", to_return->con_id);
+ sm->attach_server_session(to_return);
+ return HSM_DONE;
+ }
+ }
+
+ b = b->hash_link.next;
+ }
+
+ return HSM_NOT_FOUND;
+}
+
HSMresult_t
-HttpSessionManager::acquire_session(Continuation * cont, unsigned int ip, int
port,
- const char *hostname, HttpClientSession *
ua_session, HttpSM * sm)
+HttpSessionManager::acquire_session(Continuation *cont, unsigned int ip, int
port,
+ const char *hostname, HttpClientSession
*ua_session, HttpSM *sm)
{
NOWARN_UNUSED(cont);
HttpServerSession *to_return = NULL;
- // We compute the mmh for matching the hostname as the last
- // check for a match between the session the HttpSM is
- // looking for and the sessions we have. The reason it's
- // the last check is to save the cycles of needless
- // computing extra mmhs. We have to use the hostname
+ // We compute the mmh for matching the hostname as the last
+ // check for a match between the session the HttpSM is looking
+ // for and the sessions we have. We have to use the hostname
// as part of the match because some stupid servers can't
// handle getting request for different virtual hosts over
// the same keep-alive session (INKqa05429).
- // Also, note the ip is required as well to maintain client
+ //
+ // Also, note the ip is required as well to maintain client
// to server affinity so that we don't break certain types
// of authentication.
- bool hash_computed = false;
INK_MD5 hostname_hash;
+ bool hash_computed = false;
// First check to see if there is a server session bound
// to the user agent session
@@ -199,9 +222,10 @@ HttpSessionManager::acquire_session(Cont
ua_session->attach_server_session(NULL);
if (to_return->server_ip == ip && to_return->server_port == port) {
-
- ink_code_MMH((unsigned char *) hostname, strlen(hostname), (unsigned
char *) &hostname_hash);
- hash_computed = true;
+ if (!hash_computed) {
+ ink_code_MMH((unsigned char *) hostname, strlen(hostname), (unsigned
char *) &hostname_hash);
+ hash_computed = true;
+ }
if (hostname_hash == to_return->hostname_hash) {
Debug("http_ss", "[%" PRId64 "] [acquire session] returning attached
session ", to_return->con_id);
@@ -216,112 +240,93 @@ HttpSessionManager::acquire_session(Cont
to_return->release();
to_return = NULL;
}
+
// Now check to see if we have a connection is our
// shared connection pool
int l1_index = FIRST_LEVEL_HASH(ip);
+ EThread *ethread = this_ethread();
ink_assert(l1_index < HSM_LEVEL1_BUCKETS);
- SessionBucket *bucket;
- ProxyMutex *bucket_mutex;
- EThread *ethread = this_ethread();
+ // Will need the hash for this lookup for sure.
+ if (!hash_computed)
+ ink_code_MMH((unsigned char *) hostname, strlen(hostname), (unsigned char
*) &hostname_hash);
+
+ if (2 == sm->t_state.txn_conf->share_server_sessions) {
+ // Initialize the per-THread buckets if necessary
+ if (NULL == ua_session->mutex->thread_holding->l1_hash) {
+ ethread->l1_hash = NEW(new SessionBucket[HSM_LEVEL1_BUCKETS]);
+ for (int i = 0; i < HSM_LEVEL1_BUCKETS; ++i)
+ ethread->l1_hash[i].mutex = ethread->mutex;
+ }
- bucket = g_l1_hash + l1_index;
- bucket_mutex = bucket->mutex;
+ return _acquire_session(ethread->l1_hash + l1_index, ip, port,
hostname_hash, sm);
+ } else {
+ SessionBucket *bucket = g_l1_hash + l1_index;
- MUTEX_TRY_LOCK(lock, bucket_mutex, ethread);
- if (lock) {
+ MUTEX_TRY_LOCK(lock, bucket->mutex, ethread);
+ if (lock) {
+ return _acquire_session(bucket, ip, port, hostname_hash, sm);
+ } else {
+ Debug("http_ss", "[acquire session] could not acquire session due to
lock contention");
+ }
+ }
- int l2_index = SECOND_LEVEL_HASH(ip);
- ink_assert(l2_index < HSM_LEVEL2_BUCKETS);
+ return HSM_RETRY;
+}
- // Check to see if an appropriate connection is in
- // the 2nd level bucket
- HttpServerSession *b;
- b = bucket->l2_hash[l2_index].head;
- while (b != NULL) {
- if (b->server_ip == ip && b->server_port == port) {
-
- if (hash_computed == false) {
- ink_code_MMH((unsigned char *) hostname, strlen(hostname), (unsigned
char *) &hostname_hash);
- hash_computed = true;
- }
- if (hostname_hash == b->hostname_hash) {
+HSMresult_t
+_release_session(SessionBucket *bucket, HttpServerSession *to_release)
+{
+ int l2_index = SECOND_LEVEL_HASH(to_release->server_ip);
- // We found a match. Since the lock for the 1st level
- // bucket is the same one that we use for the read
- // on the keep alive connection, we are safe since
- // we can not get called back from the netProcessor
- // here. The SM will do a do_io when it gets the session,
- // effectively canceling the keep-alive read
- bucket->lru_list.remove(b);
- bucket->l2_hash[l2_index].remove(b);
- b->state = HSS_ACTIVE;
- to_return = b;
- Debug("http_ss", "[%" PRId64 "] [acquire session] " "return session
from shared pool", to_return->con_id);
- sm->attach_server_session(to_return);
- return HSM_DONE;
- }
- }
+ ink_assert(l2_index < HSM_LEVEL2_BUCKETS);
- b = b->hash_link.next;
- }
+ // First insert the session on to our lists
+ bucket->lru_list.enqueue(to_release);
+ bucket->l2_hash[l2_index].push(to_release);
+ to_release->state = HSS_KA_SHARED;
+
+ // Now we need to issue a read on the connection to detect
+ // if it closes on us. We will get called back in the
+ // continuation for this bucket, ensuring we have the lock
+ // to remove the connection from our lists
+ to_release->do_io_read(bucket, INT64_MAX, to_release->read_buffer);
+
+ // Transfer control of the write side as well
+ to_release->do_io_write(bucket, 0, NULL);
+
+ // we probably don't need the active timeout set, but will leave it for now
+
to_release->get_netvc()->set_inactivity_timeout(to_release->get_netvc()->get_inactivity_timeout());
+
to_release->get_netvc()->set_active_timeout(to_release->get_netvc()->get_active_timeout());
+ Debug("http_ss", "[%" PRId64 "] [release session] " "session placed into
shared pool", to_release->con_id);
- return HSM_NOT_FOUND;
- } else {
- return HSM_RETRY;
- }
+ return HSM_DONE;
}
HSMresult_t
-HttpSessionManager::release_session(HttpServerSession * to_release)
+HttpSessionManager::release_session(HttpServerSession *to_release)
{
+ EThread *ethread = this_ethread();
int l1_index = FIRST_LEVEL_HASH(to_release->server_ip);
ink_assert(l1_index < HSM_LEVEL1_BUCKETS);
- EThread *ethread = this_ethread();
-
- ProxyMutex *bucket_mutex;
- SessionBucket *bucket;
-
-#ifdef TRANSACTION_ON_A_THREAD
- bucket = to_release->mutex->thread_holding->l1_hash + l1_index;
- bucket_mutex = to_release->mutex;
-#else
- bucket = g_l1_hash + l1_index;
- bucket_mutex = bucket->mutex;
-#endif
-
- MUTEX_TRY_LOCK(lock, bucket_mutex, ethread);
- if (lock) {
-
- int l2_index = SECOND_LEVEL_HASH(to_release->server_ip);
- ink_assert(l2_index < HSM_LEVEL2_BUCKETS);
-
- // First insert the session on to our lists
- bucket->lru_list.enqueue(to_release);
- bucket->l2_hash[l2_index].push(to_release);
- to_release->state = HSS_KA_SHARED;
-
- // Now we need to issue a read on the connection to detect
- // if it closes on us. We will get called back in the
- // continuation for this bucket, ensuring we have the lock
- // to remove the connection from our lists
- to_release->do_io_read(bucket, INT64_MAX, to_release->read_buffer);
-
- // Transfer control of the write side as well
- to_release->do_io_write(bucket, 0, NULL);
-
- // we probably don't need the active timeout set, but will leave it for now
-
to_release->get_netvc()->set_inactivity_timeout(to_release->get_netvc()->get_inactivity_timeout());
-
to_release->get_netvc()->set_active_timeout(to_release->get_netvc()->get_active_timeout());
- Debug("http_ss", "[%" PRId64 "] [release session] " "session placed into
shared pool", to_release->con_id);
- return HSM_DONE;
+ if (2 == to_release->share_session) {
+ // No need to lock on the "buckets" here, since it's per-EThread already
+ return _release_session(ethread->l1_hash + l1_index, to_release);
} else {
- Debug("http_ss", "[%" PRId64 "] [release session] could not release
session due to lock contention", to_release->con_id);
- return HSM_RETRY;
+ SessionBucket *bucket = g_l1_hash + l1_index;
+
+ MUTEX_TRY_LOCK(lock, bucket->mutex, ethread);
+ if (lock) {
+ return _release_session(bucket, to_release);
+ } else {
+ Debug("http_ss", "[%" PRId64 "] [release session] could not release
session due to lock contention", to_release->con_id);
+ }
}
+
+ return HSM_RETRY;
}
Modified: trafficserver/traffic/trunk/proxy/http/HttpSessionManager.h
URL:
http://svn.apache.org/viewvc/trafficserver/traffic/trunk/proxy/http/HttpSessionManager.h?rev=1171160&r1=1171159&r2=1171160&view=diff
==============================================================================
--- trafficserver/traffic/trunk/proxy/http/HttpSessionManager.h (original)
+++ trafficserver/traffic/trunk/proxy/http/HttpSessionManager.h Thu Sep 15
16:10:32 2011
@@ -35,7 +35,6 @@
#define _HTTP_SESSION_MANAGER_H_
#include "P_EventSystem.h"
-
#include "HttpServerSession.h"
class HttpClientSession;
@@ -49,7 +48,7 @@ class HttpSM;
#define HSM_LEVEL2_BUCKETS 3
#endif
-class SessionBucket:public Continuation
+class SessionBucket: public Continuation
{
public:
SessionBucket();
@@ -64,20 +63,21 @@ enum HSMresult_t
class HttpSessionManager
{
public:
- HttpSessionManager();
- ~HttpSessionManager();
- HSMresult_t acquire_session(Continuation * cont,
+ HttpSessionManager()
+ { }
+ ~HttpSessionManager()
+ { }
+
+ HSMresult_t acquire_session(Continuation *cont,
unsigned int ip, int port,
- const char *hostname, HttpClientSession *
ua_session, HttpSM * sm);
- HSMresult_t release_session(HttpServerSession * to_release);
+ const char *hostname, HttpClientSession
*ua_session, HttpSM *sm);
+ HSMresult_t release_session(HttpServerSession *to_release);
void purge_keepalives();
void init();
int main_handler(int event, void *data);
- // Private
- //
- // Global l1 hash. Used for the sessions that are
- // transaction on a thread bound
+private:
+ // Global l1 hash, used when there is no per-thread buckets
SessionBucket g_l1_hash[HSM_LEVEL1_BUCKETS];
};