You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by jp...@apache.org on 2014/05/20 18:44:54 UTC
[1/2] git commit: TS-2759: Rename SpdySM to SpdyClientSession
Repository: trafficserver
Updated Branches:
refs/heads/master 51dffeb61 -> 428c3d581
TS-2759: Rename SpdySM to SpdyClientSession
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/92d70eb7
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/92d70eb7
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/92d70eb7
Branch: refs/heads/master
Commit: 92d70eb7b07843da81a4e184aebd0e0b978f42eb
Parents: 51dffeb
Author: James Peach <jp...@apache.org>
Authored: Sat May 17 11:46:49 2014 -0700
Committer: James Peach <jp...@apache.org>
Committed: Tue May 20 09:43:42 2014 -0700
----------------------------------------------------------------------
proxy/spdy/Makefile.am | 10 +-
proxy/spdy/SpdyCallbacks.cc | 24 +-
proxy/spdy/SpdyCallbacks.h | 4 +-
proxy/spdy/SpdyClientSession.cc | 433 +++++++++++++++++++++++++++++++++++
proxy/spdy/SpdyClientSession.h | 144 ++++++++++++
proxy/spdy/SpdySM.cc | 433 -----------------------------------
proxy/spdy/SpdySM.h | 145 ------------
proxy/spdy/SpdySessionAccept.cc | 2 +-
8 files changed, 597 insertions(+), 598 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/92d70eb7/proxy/spdy/Makefile.am
----------------------------------------------------------------------
diff --git a/proxy/spdy/Makefile.am b/proxy/spdy/Makefile.am
index a532d5a..a3b5a36 100644
--- a/proxy/spdy/Makefile.am
+++ b/proxy/spdy/Makefile.am
@@ -37,11 +37,11 @@ libspdy_a_SOURCES = \
SpdySessionAccept.cc
if BUILD_SPDY
- libspdy_a_SOURCES += \
- SpdyCallbacks.h \
- SpdyCommon.h \
- SpdySM.h \
+libspdy_a_SOURCES += \
SpdyCallbacks.cc \
+ SpdyCallbacks.h \
+ SpdyClientSession.cc \
+ SpdyClientSession.h \
SpdyCommon.cc \
- SpdySM.cc
+ SpdyCommon.h
endif
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/92d70eb7/proxy/spdy/SpdyCallbacks.cc
----------------------------------------------------------------------
diff --git a/proxy/spdy/SpdyCallbacks.cc b/proxy/spdy/SpdyCallbacks.cc
index 647d3b5..c31a239 100644
--- a/proxy/spdy/SpdyCallbacks.cc
+++ b/proxy/spdy/SpdyCallbacks.cc
@@ -22,7 +22,7 @@
*/
#include "SpdyCallbacks.h"
-#include "SpdySM.h"
+#include "SpdyClientSession.h"
#include <arpa/inet.h>
void
@@ -50,7 +50,7 @@ spdy_callbacks_init(spdylay_session_callbacks *callbacks)
}
void
-spdy_prepare_status_response(SpdySM *sm, int stream_id, const char *status)
+spdy_prepare_status_response(SpdyClientSession *sm, int stream_id, const char *status)
{
SpdyRequest *req = sm->req_map[stream_id];
string date_str = http_date(time(0));
@@ -85,7 +85,7 @@ spdy_show_data_frame(const char *head_str, spdylay_session * /*session*/, uint8_
if (!is_debug_tag_set("spdy"))
return;
- SpdySM *sm = (SpdySM *)user_data;
+ SpdyClientSession *sm = (SpdyClientSession *)user_data;
Debug("spdy", "%s DATA frame (sm_id:%" PRIu64 ", stream_id:%d, flag:%d, length:%d)",
head_str, sm->sm_id, stream_id, flags, length);
@@ -98,7 +98,7 @@ spdy_show_ctl_frame(const char *head_str, spdylay_session * /*session*/, spdylay
if (!is_debug_tag_set("spdy"))
return;
- SpdySM *sm = (SpdySM *)user_data;
+ SpdyClientSession *sm = (SpdyClientSession *)user_data;
switch (type) {
case SPDYLAY_SYN_STREAM: {
spdylay_syn_stream *f = (spdylay_syn_stream *)frame;
@@ -170,7 +170,7 @@ spdy_fetcher_launch(SpdyRequest *req, TSFetchMethod method)
string url;
int fetch_flags;
const sockaddr *client_addr;
- SpdySM *sm = req->spdy_sm;
+ SpdyClientSession *sm = req->spdy_sm;
url = req->scheme + "://" + req->host + req->path;
client_addr = TSNetVConnRemoteAddrGet(reinterpret_cast<TSVConn>(sm->vc));
@@ -214,7 +214,7 @@ ssize_t
spdy_send_callback(spdylay_session * /*session*/, const uint8_t *data, size_t length,
int /*flags*/, void *user_data)
{
- SpdySM *sm = (SpdySM*)user_data;
+ SpdyClientSession *sm = (SpdyClientSession*)user_data;
sm->total_size += length;
TSIOBufferWrite(sm->resp_buffer, data, length);
@@ -232,7 +232,7 @@ spdy_recv_callback(spdylay_session * /*session*/, uint8_t *buf, size_t length,
TSIOBufferBlock blk, next_blk;
int64_t already, blk_len, need, wavail;
- SpdySM *sm = (SpdySM*)user_data;
+ SpdyClientSession *sm = (SpdyClientSession*)user_data;
already = 0;
blk = TSIOBufferReaderStart(sm->req_reader);
@@ -270,7 +270,7 @@ spdy_recv_callback(spdylay_session * /*session*/, uint8_t *buf, size_t length,
}
static void
-spdy_process_syn_stream_frame(SpdySM *sm, SpdyRequest *req)
+spdy_process_syn_stream_frame(SpdyClientSession *sm, SpdyRequest *req)
{
// validate request headers
for(size_t i = 0; i < req->headers.size(); ++i) {
@@ -322,7 +322,7 @@ spdy_on_ctrl_recv_callback(spdylay_session *session, spdylay_frame_type type,
{
int stream_id;
SpdyRequest *req;
- SpdySM *sm = (SpdySM*)user_data;
+ SpdyClientSession *sm = (SpdyClientSession*)user_data;
spdy_show_ctl_frame("++++RECV", session, type, frame, user_data);
@@ -369,7 +369,7 @@ spdy_on_data_chunk_recv_callback(spdylay_session * /*session*/, uint8_t /*flags*
int32_t stream_id, const uint8_t *data,
size_t len, void *user_data)
{
- SpdySM *sm = (SpdySM *)user_data;
+ SpdyClientSession *sm = (SpdyClientSession *)user_data;
SpdyRequest *req = sm->req_map[stream_id];
//
@@ -388,7 +388,7 @@ void
spdy_on_data_recv_callback(spdylay_session *session, uint8_t flags,
int32_t stream_id, int32_t length, void *user_data)
{
- SpdySM *sm = (SpdySM *)user_data;
+ SpdyClientSession *sm = (SpdyClientSession *)user_data;
SpdyRequest *req = sm->req_map[stream_id];
spdy_show_data_frame("++++RECV", session, flags, stream_id, length, user_data);
@@ -459,7 +459,7 @@ void
spdy_on_data_send_callback(spdylay_session *session, uint8_t flags,
int32_t stream_id, int32_t length, void *user_data)
{
- SpdySM *sm = (SpdySM *)user_data;
+ SpdyClientSession *sm = (SpdyClientSession *)user_data;
spdy_show_data_frame("----SEND", session, flags, stream_id, length, user_data);
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/92d70eb7/proxy/spdy/SpdyCallbacks.h
----------------------------------------------------------------------
diff --git a/proxy/spdy/SpdyCallbacks.h b/proxy/spdy/SpdyCallbacks.h
index 017eb41..ebe3c71 100644
--- a/proxy/spdy/SpdyCallbacks.h
+++ b/proxy/spdy/SpdyCallbacks.h
@@ -25,10 +25,10 @@
#define __P_SPDY_CALLBACKS_H__
#include <spdylay/spdylay.h>
-class SpdySM;
+class SpdyClientSession;
void spdy_callbacks_init(spdylay_session_callbacks *callbacks);
-void spdy_prepare_status_response(SpdySM *sm, int stream_id, const char *status);
+void spdy_prepare_status_response(SpdyClientSession *sm, int stream_id, const char *status);
/**
* @functypedef
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/92d70eb7/proxy/spdy/SpdyClientSession.cc
----------------------------------------------------------------------
diff --git a/proxy/spdy/SpdyClientSession.cc b/proxy/spdy/SpdyClientSession.cc
new file mode 100644
index 0000000..73cb4e0
--- /dev/null
+++ b/proxy/spdy/SpdyClientSession.cc
@@ -0,0 +1,433 @@
+/** @file
+
+ SpdyClientSession.cc
+
+ @section license License
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+#include "SpdyClientSession.h"
+#include "I_Net.h"
+
+static ClassAllocator<SpdyClientSession> spdyClientSessionAllocator("spdyClientSessionAllocator");
+ClassAllocator<SpdyRequest> spdyRequestAllocator("spdyRequestAllocator");
+
+static int spdy_main_handler(TSCont contp, TSEvent event, void *edata);
+static int spdy_start_handler(TSCont contp, TSEvent event, void *edata);
+static int spdy_default_handler(TSCont contp, TSEvent event, void *edata);
+static int spdy_process_read(TSEvent event, SpdyClientSession *sm);
+static int spdy_process_write(TSEvent event, SpdyClientSession *sm);
+static int spdy_process_fetch(TSEvent event, SpdyClientSession *sm, void *edata);
+static int spdy_process_fetch_header(TSEvent event, SpdyClientSession *sm, TSFetchSM fetch_sm);
+static int spdy_process_fetch_body(TSEvent event, SpdyClientSession *sm, TSFetchSM fetch_sm);
+static uint64_t g_sm_id;
+static uint64_t g_sm_cnt;
+
+void
+SpdyRequest::clear()
+{
+ if (fetch_sm)
+ TSFetchDestroy(fetch_sm);
+
+ vector<pair<string, string> >().swap(headers);
+
+ std::string().swap(url);
+ std::string().swap(host);
+ std::string().swap(path);
+ std::string().swap(scheme);
+ std::string().swap(method);
+ std::string().swap(version);
+
+ Debug("spdy", "****Delete Request[%" PRIu64 ":%d]", spdy_sm->sm_id, stream_id);
+}
+
+void
+SpdyClientSession::init(NetVConnection * netvc)
+{
+ int version, r;
+
+ atomic_inc(g_sm_cnt);
+
+ this->vc = netvc;
+ this->req_map.clear();
+
+ // XXX this has to die ... TS-2793
+ UnixNetVConnection * unixvc = reinterpret_cast<UnixNetVConnection *>(netvc);
+
+ if (unixvc->selected_next_protocol == TS_NPN_PROTOCOL_SPDY_3_1)
+ version = SPDYLAY_PROTO_SPDY3_1;
+ else if (unixvc->selected_next_protocol == TS_NPN_PROTOCOL_SPDY_3)
+ version = SPDYLAY_PROTO_SPDY3;
+ else if (unixvc->selected_next_protocol == TS_NPN_PROTOCOL_SPDY_2)
+ version = SPDYLAY_PROTO_SPDY2;
+ else
+ version = SPDYLAY_PROTO_SPDY3;
+
+ r = spdylay_session_server_new(&session, version,
+ &SPDY_CFG.spdy.callbacks, this);
+ ink_release_assert(r == 0);
+ sm_id = atomic_inc(g_sm_id);
+ total_size = 0;
+ start_time = TShrtime();
+
+ ink_assert(this->contp == NULL);
+ this->contp = TSContCreate(spdy_main_handler, TSMutexCreate());
+ TSContDataSet(this->contp, this);
+
+ this->vc->set_inactivity_timeout(HRTIME_SECONDS(SPDY_CFG.accept_no_activity_timeout));
+ this->current_handler = &spdy_start_handler;
+}
+
+void
+SpdyClientSession::clear()
+{
+ uint64_t nr_pending;
+ int last_event = event;
+ //
+ // SpdyRequest depends on SpdyClientSession,
+ // we should delete it firstly to avoid race.
+ //
+ map<int, SpdyRequest*>::iterator iter = req_map.begin();
+ map<int, SpdyRequest*>::iterator endIter = req_map.end();
+ for(; iter != endIter; ++iter) {
+ SpdyRequest *req = iter->second;
+ if (req) {
+ req->clear();
+ spdyRequestAllocator.free(req);
+ } else {
+ Error("req null in SpdSM::clear");
+ }
+ }
+ req_map.clear();
+
+ if (vc) {
+ TSVConnClose(reinterpret_cast<TSVConn>(vc));
+ vc = NULL;
+ }
+
+ if (contp) {
+ TSContDestroy(contp);
+ contp = NULL;
+ }
+
+ if (req_reader) {
+ TSIOBufferReaderFree(req_reader);
+ req_reader = NULL;
+ }
+
+ if (req_buffer) {
+ TSIOBufferDestroy(req_buffer);
+ req_buffer = NULL;
+ }
+
+ if (resp_reader) {
+ TSIOBufferReaderFree(resp_reader);
+ resp_reader = NULL;
+ }
+
+ if (resp_buffer) {
+ TSIOBufferDestroy(resp_buffer);
+ resp_buffer = NULL;
+ }
+
+ if (session) {
+ spdylay_session_del(session);
+ session = NULL;
+ }
+
+ nr_pending = atomic_dec(g_sm_cnt);
+ Debug("spdy-free", "****Delete SpdyClientSession[%" PRIu64 "], last event:%d, nr_pending:%" PRIu64,
+ sm_id, last_event, --nr_pending);
+}
+
+void
+spdy_sm_create(NetVConnection * netvc, MIOBuffer * iobuf, IOBufferReader * reader)
+{
+ SpdyClientSession *sm;
+
+ sm = spdyClientSessionAllocator.alloc();
+ sm->init(netvc);
+
+ sm->req_buffer = iobuf ? reinterpret_cast<TSIOBuffer>(iobuf) : TSIOBufferCreate();
+ sm->req_reader = reader ? reinterpret_cast<TSIOBufferReader>(reader) : TSIOBufferReaderAlloc(sm->req_buffer);
+
+ sm->resp_buffer = TSIOBufferCreate();
+ sm->resp_reader = TSIOBufferReaderAlloc(sm->resp_buffer);
+
+ TSContSchedule(sm->contp, 0, TS_THREAD_POOL_DEFAULT); // schedule now
+}
+
+static int
+spdy_main_handler(TSCont contp, TSEvent event, void *edata)
+{
+ SpdyClientSession *sm;
+ SpdyClientSessionHandler spdy_current_handler;
+
+ sm = (SpdyClientSession*)TSContDataGet(contp);
+ spdy_current_handler = sm->current_handler;
+
+ return (*spdy_current_handler) (contp, event, edata);
+}
+
+static int
+spdy_start_handler(TSCont contp, TSEvent /*event*/, void * /*data*/)
+{
+ int r;
+ spdylay_settings_entry entry;
+
+ SpdyClientSession *sm = (SpdyClientSession*)TSContDataGet(contp);
+
+ if (TSIOBufferReaderAvail(sm->req_reader) > 0) {
+ spdy_process_read(TS_EVENT_VCONN_WRITE_READY, sm);
+ }
+
+ sm->read_vio = (TSVIO)sm->vc->do_io_read(reinterpret_cast<Continuation *>(contp), INT64_MAX, reinterpret_cast<MIOBuffer *>(sm->req_buffer));
+ sm->write_vio = (TSVIO)sm->vc->do_io_write(reinterpret_cast<Continuation *>(contp), INT64_MAX, reinterpret_cast<IOBufferReader *>(sm->resp_reader));
+
+ sm->current_handler = &spdy_default_handler;
+
+ /* send initial settings frame */
+ entry.settings_id = SPDYLAY_SETTINGS_MAX_CONCURRENT_STREAMS;
+ entry.value = SPDY_CFG.spdy.max_concurrent_streams;
+ entry.flags = SPDYLAY_ID_FLAG_SETTINGS_NONE;
+
+ r = spdylay_submit_settings(sm->session, SPDYLAY_FLAG_SETTINGS_NONE, &entry, 1);
+ TSAssert(r == 0);
+
+ TSVIOReenable(sm->write_vio);
+ return 0;
+}
+
+static int
+spdy_default_handler(TSCont contp, TSEvent event, void *edata)
+{
+ int ret = 0;
+ bool from_fetch = false;
+ SpdyClientSession *sm = (SpdyClientSession*)TSContDataGet(contp);
+ sm->event = event;
+
+ if (edata == sm->read_vio) {
+ Debug("spdy", "++++[READ EVENT]");
+ if (event != TS_EVENT_VCONN_READ_READY &&
+ event != TS_EVENT_VCONN_READ_COMPLETE) {
+ ret = -1;
+ goto out;
+ }
+ ret = spdy_process_read(event, sm);
+ } else if (edata == sm->write_vio) {
+ Debug("spdy", "----[WRITE EVENT]");
+ if (event != TS_EVENT_VCONN_WRITE_READY &&
+ event != TS_EVENT_VCONN_WRITE_COMPLETE) {
+ ret = -1;
+ goto out;
+ }
+ ret = spdy_process_write(event, sm);
+ } else {
+ from_fetch = true;
+ ret = spdy_process_fetch(event, sm, edata);
+ }
+
+ Debug("spdy-event", "++++SpdyClientSession[%" PRIu64 "], EVENT:%d, ret:%d, nr_pending:%" PRIu64,
+ sm->sm_id, event, ret, g_sm_cnt);
+out:
+ if (ret) {
+ sm->clear();
+ spdyClientSessionAllocator.free(sm);
+ } else if (!from_fetch) {
+ sm->vc->set_inactivity_timeout(HRTIME_SECONDS(SPDY_CFG.no_activity_timeout_in));
+ }
+
+ return 0;
+}
+
+static int
+spdy_process_read(TSEvent /* event ATS_UNUSED */, SpdyClientSession *sm)
+{
+ return spdylay_session_recv(sm->session);
+}
+
+static int
+spdy_process_write(TSEvent /* event ATS_UNUSED */, SpdyClientSession *sm)
+{
+ int ret;
+
+ ret = spdylay_session_send(sm->session);
+
+ if (TSIOBufferReaderAvail(sm->resp_reader) > 0)
+ TSVIOReenable(sm->write_vio);
+ else {
+ Debug("spdy", "----TOTAL SEND (sm_id:%" PRIu64 ", total_size:%" PRIu64 ", total_send:%" PRId64 ")",
+ sm->sm_id, sm->total_size, TSVIONDoneGet(sm->write_vio));
+
+ //
+ // We should reenable read_vio when no data to be written,
+ // otherwise it could lead to hang issue when client POST
+ // data is waiting to be read.
+ //
+ TSVIOReenable(sm->read_vio);
+ }
+
+ return ret;
+}
+
+static int
+spdy_process_fetch(TSEvent event, SpdyClientSession *sm, void *edata)
+{
+ int ret = -1;
+ TSFetchSM fetch_sm = (TSFetchSM)edata;
+ SpdyRequest *req = (SpdyRequest *)TSFetchUserDataGet(fetch_sm);
+
+ switch ((int)event) {
+
+ case TS_FETCH_EVENT_EXT_HEAD_DONE:
+ Debug("spdy", "----[FETCH HEADER DONE]");
+ ret = spdy_process_fetch_header(event, sm, fetch_sm);
+ break;
+
+ case TS_FETCH_EVENT_EXT_BODY_READY:
+ Debug("spdy", "----[FETCH BODY READY]");
+ ret = spdy_process_fetch_body(event, sm, fetch_sm);
+ break;
+
+ case TS_FETCH_EVENT_EXT_BODY_DONE:
+ Debug("spdy", "----[FETCH BODY DONE]");
+ req->fetch_body_completed = true;
+ ret = spdy_process_fetch_body(event, sm, fetch_sm);
+ break;
+
+ default:
+ Debug("spdy", "----[FETCH ERROR]");
+ if (req->fetch_body_completed)
+ ret = 0; // Ignore fetch errors after FETCH BODY DONE
+ else
+ req->fetch_sm = NULL;
+ break;
+ }
+
+ if (ret) {
+ spdy_prepare_status_response(sm, req->stream_id, STATUS_500);
+ sm->req_map.erase(req->stream_id);
+ req->clear();
+ spdyRequestAllocator.free(req);
+ }
+
+ return 0;
+}
+
+static int
+spdy_process_fetch_header(TSEvent /*event*/, SpdyClientSession *sm, TSFetchSM fetch_sm)
+{
+ int ret;
+ SpdyRequest *req = (SpdyRequest *)TSFetchUserDataGet(fetch_sm);
+ SpdyNV spdy_nv(fetch_sm);
+
+ Debug("spdy", "----spdylay_submit_syn_reply");
+ ret = spdylay_submit_syn_reply(sm->session,
+ SPDYLAY_CTRL_FLAG_NONE, req->stream_id,
+ spdy_nv.nv);
+
+ TSVIOReenable(sm->write_vio);
+ return ret;
+}
+
+static ssize_t
+spdy_read_fetch_body_callback(spdylay_session * /*session*/, int32_t stream_id,
+ uint8_t *buf, size_t length, int *eof,
+ spdylay_data_source *source, void *user_data)
+{
+
+ static int g_call_cnt;
+ int64_t already;
+
+ SpdyClientSession *sm = (SpdyClientSession *)user_data;
+ SpdyRequest *req = (SpdyRequest *)source->ptr;
+
+ //
+ // req has been deleted, ignore this data.
+ //
+ if (req != sm->req_map[stream_id]) {
+ Debug("spdy", " stream_id:%d, call:%d, req has been deleted, return 0",
+ stream_id, g_call_cnt);
+ *eof = 1;
+ return 0;
+ }
+
+ already = TSFetchReadData(req->fetch_sm, buf, length);
+
+ Debug("spdy", " stream_id:%d, call:%d, length:%ld, already:%" PRId64,
+ stream_id, g_call_cnt, length, already);
+ if (SPDY_CFG.spdy.verbose)
+ MD5_Update(&req->recv_md5, buf, already);
+
+ TSVIOReenable(sm->write_vio);
+ g_call_cnt++;
+
+ req->fetch_data_len += already;
+ if (already < (int64_t)length) {
+ if (req->event == TS_FETCH_EVENT_EXT_BODY_DONE) {
+ TSHRTime end_time = TShrtime();
+ Debug("spdy", "----Request[%" PRIu64 ":%d] %s %lld %d", sm->sm_id, req->stream_id,
+ req->url.c_str(), (end_time - req->start_time)/TS_HRTIME_MSECOND,
+ req->fetch_data_len);
+ unsigned char digest[MD5_DIGEST_LENGTH];
+ if (SPDY_CFG.spdy.verbose ) {
+ MD5_Final(digest, &req->recv_md5);
+ Debug("spdy", "----recv md5sum: ");
+ for (int i = 0; i < MD5_DIGEST_LENGTH; i++) {
+ Debug("spdy", "%02x", digest[i]);
+ }
+ }
+ *eof = 1;
+ sm->req_map.erase(stream_id);
+ req->clear();
+ spdyRequestAllocator.free(req);
+ } else if (already == 0) {
+ req->need_resume_data = true;
+ return SPDYLAY_ERR_DEFERRED;
+ }
+ }
+
+ return already;
+}
+
+static int
+spdy_process_fetch_body(TSEvent event, SpdyClientSession *sm, TSFetchSM fetch_sm)
+{
+ int ret = 0;
+ spdylay_data_provider data_prd;
+ SpdyRequest *req = (SpdyRequest *)TSFetchUserDataGet(fetch_sm);
+ req->event = event;
+
+ data_prd.source.ptr = (void *)req;
+ data_prd.read_callback = spdy_read_fetch_body_callback;
+
+ if (!req->has_submitted_data) {
+ req->has_submitted_data = true;
+ Debug("spdy", "----spdylay_submit_data");
+ ret = spdylay_submit_data(sm->session, req->stream_id,
+ SPDYLAY_DATA_FLAG_FIN, &data_prd);
+ } else if (req->need_resume_data) {
+ Debug("spdy", "----spdylay_session_resume_data");
+ ret = spdylay_session_resume_data(sm->session, req->stream_id);
+ if (ret == SPDYLAY_ERR_INVALID_ARGUMENT)
+ ret = 0;
+ }
+
+ TSVIOReenable(sm->write_vio);
+ return ret;
+}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/92d70eb7/proxy/spdy/SpdyClientSession.h
----------------------------------------------------------------------
diff --git a/proxy/spdy/SpdyClientSession.h b/proxy/spdy/SpdyClientSession.h
new file mode 100644
index 0000000..00a86b9
--- /dev/null
+++ b/proxy/spdy/SpdyClientSession.h
@@ -0,0 +1,144 @@
+/** @file
+
+ SpdyClientSession.h
+
+ @section license License
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+#ifndef __P_SPDY_SM_H__
+#define __P_SPDY_SM_H__
+
+#include "SpdyCommon.h"
+#include "SpdyCallbacks.h"
+#include <openssl/md5.h>
+
+class SpdyClientSession;
+typedef int (*SpdyClientSessionHandler) (TSCont contp, TSEvent event, void *data);
+
+class SpdyRequest
+{
+public:
+ SpdyRequest():
+ spdy_sm(NULL), stream_id(-1), fetch_sm(NULL),
+ has_submitted_data(false), need_resume_data(false),
+ fetch_data_len(0), delta_window_size(0),
+ fetch_body_completed(false)
+ {
+ }
+
+ SpdyRequest(SpdyClientSession *sm, int id):
+ spdy_sm(NULL), stream_id(-1), fetch_sm(NULL),
+ has_submitted_data(false), need_resume_data(false),
+ fetch_data_len(0), delta_window_size(0),
+ fetch_body_completed(false)
+ {
+ init(sm, id);
+ }
+
+ ~SpdyRequest()
+ {
+ clear();
+ }
+
+ void init(SpdyClientSession *sm, int id)
+ {
+ spdy_sm = sm;
+ stream_id = id;
+ headers.clear();
+
+ MD5_Init(&recv_md5);
+ start_time = TShrtime();
+ }
+
+ void clear();
+
+ void append_nv(char **nv)
+ {
+ for(int i = 0; nv[i]; i += 2) {
+ headers.push_back(make_pair(nv[i], nv[i+1]));
+ }
+ }
+
+public:
+ int event;
+ SpdyClientSession *spdy_sm;
+ int stream_id;
+ TSHRTime start_time;
+ TSFetchSM fetch_sm;
+ bool has_submitted_data;
+ bool need_resume_data;
+ int fetch_data_len;
+ int delta_window_size;
+ bool fetch_body_completed;
+ vector<pair<string, string> > headers;
+
+ string url;
+ string host;
+ string path;
+ string scheme;
+ string method;
+ string version;
+
+ MD5_CTX recv_md5;
+};
+
+class SpdyClientSession
+{
+
+public:
+
+ SpdyClientSession() {
+ }
+
+ ~SpdyClientSession() {
+ clear();
+ }
+
+ void init(NetVConnection * netvc);
+ void clear();
+
+ int64_t sm_id;
+ uint64_t total_size;
+ TSHRTime start_time;
+
+ NetVConnection * vc;
+ TSCont contp;
+
+ TSIOBuffer req_buffer;
+ TSIOBufferReader req_reader;
+
+ TSIOBuffer resp_buffer;
+ TSIOBufferReader resp_reader;
+
+ TSVIO read_vio;
+ TSVIO write_vio;
+
+ SpdyClientSessionHandler current_handler;
+
+ int event;
+ spdylay_session *session;
+
+ map<int32_t, SpdyRequest*> req_map;
+};
+
+void spdy_sm_create(NetVConnection * netvc, MIOBuffer * iobuf, IOBufferReader * reader);
+
+extern ClassAllocator<SpdyRequest> spdyRequestAllocator;
+
+#endif
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/92d70eb7/proxy/spdy/SpdySM.cc
----------------------------------------------------------------------
diff --git a/proxy/spdy/SpdySM.cc b/proxy/spdy/SpdySM.cc
deleted file mode 100644
index df66f39..0000000
--- a/proxy/spdy/SpdySM.cc
+++ /dev/null
@@ -1,433 +0,0 @@
-/** @file
-
- SpdySM.cc
-
- @section license License
-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
-#include "SpdySM.h"
-#include "I_Net.h"
-
-ClassAllocator<SpdySM> spdySMAllocator("SpdySMAllocator");
-ClassAllocator<SpdyRequest> spdyRequestAllocator("SpdyRequestAllocator");
-
-static int spdy_main_handler(TSCont contp, TSEvent event, void *edata);
-static int spdy_start_handler(TSCont contp, TSEvent event, void *edata);
-static int spdy_default_handler(TSCont contp, TSEvent event, void *edata);
-static int spdy_process_read(TSEvent event, SpdySM *sm);
-static int spdy_process_write(TSEvent event, SpdySM *sm);
-static int spdy_process_fetch(TSEvent event, SpdySM *sm, void *edata);
-static int spdy_process_fetch_header(TSEvent event, SpdySM *sm, TSFetchSM fetch_sm);
-static int spdy_process_fetch_body(TSEvent event, SpdySM *sm, TSFetchSM fetch_sm);
-static uint64_t g_sm_id;
-static uint64_t g_sm_cnt;
-
-void
-SpdyRequest::clear()
-{
- if (fetch_sm)
- TSFetchDestroy(fetch_sm);
-
- vector<pair<string, string> >().swap(headers);
-
- std::string().swap(url);
- std::string().swap(host);
- std::string().swap(path);
- std::string().swap(scheme);
- std::string().swap(method);
- std::string().swap(version);
-
- Debug("spdy", "****Delete Request[%" PRIu64 ":%d]", spdy_sm->sm_id, stream_id);
-}
-
-void
-SpdySM::init(NetVConnection * netvc)
-{
- int version, r;
-
- atomic_inc(g_sm_cnt);
-
- this->vc = netvc;
- this->req_map.clear();
-
- // XXX this has to die ... TS-2793
- UnixNetVConnection * unixvc = reinterpret_cast<UnixNetVConnection *>(netvc);
-
- if (unixvc->selected_next_protocol == TS_NPN_PROTOCOL_SPDY_3_1)
- version = SPDYLAY_PROTO_SPDY3_1;
- else if (unixvc->selected_next_protocol == TS_NPN_PROTOCOL_SPDY_3)
- version = SPDYLAY_PROTO_SPDY3;
- else if (unixvc->selected_next_protocol == TS_NPN_PROTOCOL_SPDY_2)
- version = SPDYLAY_PROTO_SPDY2;
- else
- version = SPDYLAY_PROTO_SPDY3;
-
- r = spdylay_session_server_new(&session, version,
- &SPDY_CFG.spdy.callbacks, this);
- ink_release_assert(r == 0);
- sm_id = atomic_inc(g_sm_id);
- total_size = 0;
- start_time = TShrtime();
-
- ink_assert(this->contp == NULL);
- this->contp = TSContCreate(spdy_main_handler, TSMutexCreate());
- TSContDataSet(this->contp, this);
-
- this->vc->set_inactivity_timeout(HRTIME_SECONDS(SPDY_CFG.accept_no_activity_timeout));
- this->current_handler = &spdy_start_handler;
-}
-
-void
-SpdySM::clear()
-{
- uint64_t nr_pending;
- int last_event = event;
- //
- // SpdyRequest depends on SpdySM,
- // we should delete it firstly to avoid race.
- //
- map<int, SpdyRequest*>::iterator iter = req_map.begin();
- map<int, SpdyRequest*>::iterator endIter = req_map.end();
- for(; iter != endIter; ++iter) {
- SpdyRequest *req = iter->second;
- if (req) {
- req->clear();
- spdyRequestAllocator.free(req);
- } else {
- Error("req null in SpdSM::clear");
- }
- }
- req_map.clear();
-
- if (vc) {
- TSVConnClose(reinterpret_cast<TSVConn>(vc));
- vc = NULL;
- }
-
- if (contp) {
- TSContDestroy(contp);
- contp = NULL;
- }
-
- if (req_reader) {
- TSIOBufferReaderFree(req_reader);
- req_reader = NULL;
- }
-
- if (req_buffer) {
- TSIOBufferDestroy(req_buffer);
- req_buffer = NULL;
- }
-
- if (resp_reader) {
- TSIOBufferReaderFree(resp_reader);
- resp_reader = NULL;
- }
-
- if (resp_buffer) {
- TSIOBufferDestroy(resp_buffer);
- resp_buffer = NULL;
- }
-
- if (session) {
- spdylay_session_del(session);
- session = NULL;
- }
-
- nr_pending = atomic_dec(g_sm_cnt);
- Debug("spdy-free", "****Delete SpdySM[%" PRIu64 "], last event:%d, nr_pending:%" PRIu64,
- sm_id, last_event, --nr_pending);
-}
-
-void
-spdy_sm_create(NetVConnection * netvc, MIOBuffer * iobuf, IOBufferReader * reader)
-{
- SpdySM *sm;
-
- sm = spdySMAllocator.alloc();
- sm->init(netvc);
-
- sm->req_buffer = iobuf ? reinterpret_cast<TSIOBuffer>(iobuf) : TSIOBufferCreate();
- sm->req_reader = reader ? reinterpret_cast<TSIOBufferReader>(reader) : TSIOBufferReaderAlloc(sm->req_buffer);
-
- sm->resp_buffer = TSIOBufferCreate();
- sm->resp_reader = TSIOBufferReaderAlloc(sm->resp_buffer);
-
- TSContSchedule(sm->contp, 0, TS_THREAD_POOL_DEFAULT); // schedule now
-}
-
-static int
-spdy_main_handler(TSCont contp, TSEvent event, void *edata)
-{
- SpdySM *sm;
- SpdySMHandler spdy_current_handler;
-
- sm = (SpdySM*)TSContDataGet(contp);
- spdy_current_handler = sm->current_handler;
-
- return (*spdy_current_handler) (contp, event, edata);
-}
-
-static int
-spdy_start_handler(TSCont contp, TSEvent /*event*/, void * /*data*/)
-{
- int r;
- spdylay_settings_entry entry;
-
- SpdySM *sm = (SpdySM*)TSContDataGet(contp);
-
- if (TSIOBufferReaderAvail(sm->req_reader) > 0) {
- spdy_process_read(TS_EVENT_VCONN_WRITE_READY, sm);
- }
-
- sm->read_vio = (TSVIO)sm->vc->do_io_read(reinterpret_cast<Continuation *>(contp), INT64_MAX, reinterpret_cast<MIOBuffer *>(sm->req_buffer));
- sm->write_vio = (TSVIO)sm->vc->do_io_write(reinterpret_cast<Continuation *>(contp), INT64_MAX, reinterpret_cast<IOBufferReader *>(sm->resp_reader));
-
- sm->current_handler = &spdy_default_handler;
-
- /* send initial settings frame */
- entry.settings_id = SPDYLAY_SETTINGS_MAX_CONCURRENT_STREAMS;
- entry.value = SPDY_CFG.spdy.max_concurrent_streams;
- entry.flags = SPDYLAY_ID_FLAG_SETTINGS_NONE;
-
- r = spdylay_submit_settings(sm->session, SPDYLAY_FLAG_SETTINGS_NONE, &entry, 1);
- TSAssert(r == 0);
-
- TSVIOReenable(sm->write_vio);
- return 0;
-}
-
-static int
-spdy_default_handler(TSCont contp, TSEvent event, void *edata)
-{
- int ret = 0;
- bool from_fetch = false;
- SpdySM *sm = (SpdySM*)TSContDataGet(contp);
- sm->event = event;
-
- if (edata == sm->read_vio) {
- Debug("spdy", "++++[READ EVENT]");
- if (event != TS_EVENT_VCONN_READ_READY &&
- event != TS_EVENT_VCONN_READ_COMPLETE) {
- ret = -1;
- goto out;
- }
- ret = spdy_process_read(event, sm);
- } else if (edata == sm->write_vio) {
- Debug("spdy", "----[WRITE EVENT]");
- if (event != TS_EVENT_VCONN_WRITE_READY &&
- event != TS_EVENT_VCONN_WRITE_COMPLETE) {
- ret = -1;
- goto out;
- }
- ret = spdy_process_write(event, sm);
- } else {
- from_fetch = true;
- ret = spdy_process_fetch(event, sm, edata);
- }
-
- Debug("spdy-event", "++++SpdySM[%" PRIu64 "], EVENT:%d, ret:%d, nr_pending:%" PRIu64,
- sm->sm_id, event, ret, g_sm_cnt);
-out:
- if (ret) {
- sm->clear();
- spdySMAllocator.free(sm);
- } else if (!from_fetch) {
- sm->vc->set_inactivity_timeout(HRTIME_SECONDS(SPDY_CFG.no_activity_timeout_in));
- }
-
- return 0;
-}
-
-static int
-spdy_process_read(TSEvent /* event ATS_UNUSED */, SpdySM *sm)
-{
- return spdylay_session_recv(sm->session);
-}
-
-static int
-spdy_process_write(TSEvent /* event ATS_UNUSED */, SpdySM *sm)
-{
- int ret;
-
- ret = spdylay_session_send(sm->session);
-
- if (TSIOBufferReaderAvail(sm->resp_reader) > 0)
- TSVIOReenable(sm->write_vio);
- else {
- Debug("spdy", "----TOTAL SEND (sm_id:%" PRIu64 ", total_size:%" PRIu64 ", total_send:%" PRId64 ")",
- sm->sm_id, sm->total_size, TSVIONDoneGet(sm->write_vio));
-
- //
- // We should reenable read_vio when no data to be written,
- // otherwise it could lead to hang issue when client POST
- // data is waiting to be read.
- //
- TSVIOReenable(sm->read_vio);
- }
-
- return ret;
-}
-
-static int
-spdy_process_fetch(TSEvent event, SpdySM *sm, void *edata)
-{
- int ret = -1;
- TSFetchSM fetch_sm = (TSFetchSM)edata;
- SpdyRequest *req = (SpdyRequest *)TSFetchUserDataGet(fetch_sm);
-
- switch ((int)event) {
-
- case TS_FETCH_EVENT_EXT_HEAD_DONE:
- Debug("spdy", "----[FETCH HEADER DONE]");
- ret = spdy_process_fetch_header(event, sm, fetch_sm);
- break;
-
- case TS_FETCH_EVENT_EXT_BODY_READY:
- Debug("spdy", "----[FETCH BODY READY]");
- ret = spdy_process_fetch_body(event, sm, fetch_sm);
- break;
-
- case TS_FETCH_EVENT_EXT_BODY_DONE:
- Debug("spdy", "----[FETCH BODY DONE]");
- req->fetch_body_completed = true;
- ret = spdy_process_fetch_body(event, sm, fetch_sm);
- break;
-
- default:
- Debug("spdy", "----[FETCH ERROR]");
- if (req->fetch_body_completed)
- ret = 0; // Ignore fetch errors after FETCH BODY DONE
- else
- req->fetch_sm = NULL;
- break;
- }
-
- if (ret) {
- spdy_prepare_status_response(sm, req->stream_id, STATUS_500);
- sm->req_map.erase(req->stream_id);
- req->clear();
- spdyRequestAllocator.free(req);
- }
-
- return 0;
-}
-
-static int
-spdy_process_fetch_header(TSEvent /*event*/, SpdySM *sm, TSFetchSM fetch_sm)
-{
- int ret;
- SpdyRequest *req = (SpdyRequest *)TSFetchUserDataGet(fetch_sm);
- SpdyNV spdy_nv(fetch_sm);
-
- Debug("spdy", "----spdylay_submit_syn_reply");
- ret = spdylay_submit_syn_reply(sm->session,
- SPDYLAY_CTRL_FLAG_NONE, req->stream_id,
- spdy_nv.nv);
-
- TSVIOReenable(sm->write_vio);
- return ret;
-}
-
-static ssize_t
-spdy_read_fetch_body_callback(spdylay_session * /*session*/, int32_t stream_id,
- uint8_t *buf, size_t length, int *eof,
- spdylay_data_source *source, void *user_data)
-{
-
- static int g_call_cnt;
- int64_t already;
-
- SpdySM *sm = (SpdySM *)user_data;
- SpdyRequest *req = (SpdyRequest *)source->ptr;
-
- //
- // req has been deleted, ignore this data.
- //
- if (req != sm->req_map[stream_id]) {
- Debug("spdy", " stream_id:%d, call:%d, req has been deleted, return 0",
- stream_id, g_call_cnt);
- *eof = 1;
- return 0;
- }
-
- already = TSFetchReadData(req->fetch_sm, buf, length);
-
- Debug("spdy", " stream_id:%d, call:%d, length:%ld, already:%" PRId64,
- stream_id, g_call_cnt, length, already);
- if (SPDY_CFG.spdy.verbose)
- MD5_Update(&req->recv_md5, buf, already);
-
- TSVIOReenable(sm->write_vio);
- g_call_cnt++;
-
- req->fetch_data_len += already;
- if (already < (int64_t)length) {
- if (req->event == TS_FETCH_EVENT_EXT_BODY_DONE) {
- TSHRTime end_time = TShrtime();
- Debug("spdy", "----Request[%" PRIu64 ":%d] %s %lld %d", sm->sm_id, req->stream_id,
- req->url.c_str(), (end_time - req->start_time)/TS_HRTIME_MSECOND,
- req->fetch_data_len);
- unsigned char digest[MD5_DIGEST_LENGTH];
- if (SPDY_CFG.spdy.verbose ) {
- MD5_Final(digest, &req->recv_md5);
- Debug("spdy", "----recv md5sum: ");
- for (int i = 0; i < MD5_DIGEST_LENGTH; i++) {
- Debug("spdy", "%02x", digest[i]);
- }
- }
- *eof = 1;
- sm->req_map.erase(stream_id);
- req->clear();
- spdyRequestAllocator.free(req);
- } else if (already == 0) {
- req->need_resume_data = true;
- return SPDYLAY_ERR_DEFERRED;
- }
- }
-
- return already;
-}
-
-static int
-spdy_process_fetch_body(TSEvent event, SpdySM *sm, TSFetchSM fetch_sm)
-{
- int ret = 0;
- spdylay_data_provider data_prd;
- SpdyRequest *req = (SpdyRequest *)TSFetchUserDataGet(fetch_sm);
- req->event = event;
-
- data_prd.source.ptr = (void *)req;
- data_prd.read_callback = spdy_read_fetch_body_callback;
-
- if (!req->has_submitted_data) {
- req->has_submitted_data = true;
- Debug("spdy", "----spdylay_submit_data");
- ret = spdylay_submit_data(sm->session, req->stream_id,
- SPDYLAY_DATA_FLAG_FIN, &data_prd);
- } else if (req->need_resume_data) {
- Debug("spdy", "----spdylay_session_resume_data");
- ret = spdylay_session_resume_data(sm->session, req->stream_id);
- if (ret == SPDYLAY_ERR_INVALID_ARGUMENT)
- ret = 0;
- }
-
- TSVIOReenable(sm->write_vio);
- return ret;
-}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/92d70eb7/proxy/spdy/SpdySM.h
----------------------------------------------------------------------
diff --git a/proxy/spdy/SpdySM.h b/proxy/spdy/SpdySM.h
deleted file mode 100644
index 4a6da83..0000000
--- a/proxy/spdy/SpdySM.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/** @file
-
- SpdySM.h
-
- @section license License
-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
-#ifndef __P_SPDY_SM_H__
-#define __P_SPDY_SM_H__
-
-#include "SpdyCommon.h"
-#include "SpdyCallbacks.h"
-#include <openssl/md5.h>
-
-class SpdySM;
-typedef int (*SpdySMHandler) (TSCont contp, TSEvent event, void *data);
-
-class SpdyRequest
-{
-public:
- SpdyRequest():
- spdy_sm(NULL), stream_id(-1), fetch_sm(NULL),
- has_submitted_data(false), need_resume_data(false),
- fetch_data_len(0), delta_window_size(0),
- fetch_body_completed(false)
- {
- }
-
- SpdyRequest(SpdySM *sm, int id):
- spdy_sm(NULL), stream_id(-1), fetch_sm(NULL),
- has_submitted_data(false), need_resume_data(false),
- fetch_data_len(0), delta_window_size(0),
- fetch_body_completed(false)
- {
- init(sm, id);
- }
-
- ~SpdyRequest()
- {
- clear();
- }
-
- void init(SpdySM *sm, int id)
- {
- spdy_sm = sm;
- stream_id = id;
- headers.clear();
-
- MD5_Init(&recv_md5);
- start_time = TShrtime();
- }
-
- void clear();
-
- void append_nv(char **nv)
- {
- for(int i = 0; nv[i]; i += 2) {
- headers.push_back(make_pair(nv[i], nv[i+1]));
- }
- }
-
-public:
- int event;
- SpdySM *spdy_sm;
- int stream_id;
- TSHRTime start_time;
- TSFetchSM fetch_sm;
- bool has_submitted_data;
- bool need_resume_data;
- int fetch_data_len;
- int delta_window_size;
- bool fetch_body_completed;
- vector<pair<string, string> > headers;
-
- string url;
- string host;
- string path;
- string scheme;
- string method;
- string version;
-
- MD5_CTX recv_md5;
-};
-
-class SpdySM
-{
-
-public:
-
- SpdySM() {
- }
-
- ~SpdySM() {
- clear();
- }
-
- void init(NetVConnection * netvc);
- void clear();
-
- int64_t sm_id;
- uint64_t total_size;
- TSHRTime start_time;
-
- NetVConnection * vc;
- TSCont contp;
-
- TSIOBuffer req_buffer;
- TSIOBufferReader req_reader;
-
- TSIOBuffer resp_buffer;
- TSIOBufferReader resp_reader;
-
- TSVIO read_vio;
- TSVIO write_vio;
-
- SpdySMHandler current_handler;
-
- int event;
- spdylay_session *session;
-
- map<int32_t, SpdyRequest*> req_map;
-};
-
-void spdy_sm_create(NetVConnection * netvc, MIOBuffer * iobuf, IOBufferReader * reader);
-
-extern ClassAllocator<SpdySM> spdySMAllocator;
-extern ClassAllocator<SpdyRequest> spdyRequestAllocator;
-
-#endif
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/92d70eb7/proxy/spdy/SpdySessionAccept.cc
----------------------------------------------------------------------
diff --git a/proxy/spdy/SpdySessionAccept.cc b/proxy/spdy/SpdySessionAccept.cc
index 00fd024..79b465d 100644
--- a/proxy/spdy/SpdySessionAccept.cc
+++ b/proxy/spdy/SpdySessionAccept.cc
@@ -25,7 +25,7 @@
#include "Error.h"
#if TS_HAS_SPDY
-#include "SpdySM.h"
+#include "SpdyClientSession.h"
#endif
SpdySessionAccept::SpdySessionAccept(Continuation *ep)
[2/2] git commit: TS-2759: make SpdyClientSession a continuation
Posted by jp...@apache.org.
TS-2759: make SpdyClientSession a continuation
Instead of using a separate TSCont to receive session events, make
SpdyClientSession a Continuation and just handle events directly.
This also removes an extra event handling indirection.
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/428c3d58
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/428c3d58
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/428c3d58
Branch: refs/heads/master
Commit: 428c3d581b6daa6e7355536157762cf708744898
Parents: 92d70eb
Author: James Peach <jp...@apache.org>
Authored: Sat May 17 12:16:32 2014 -0700
Committer: James Peach <jp...@apache.org>
Committed: Tue May 20 09:43:50 2014 -0700
----------------------------------------------------------------------
proxy/spdy/SpdyCallbacks.cc | 2 +-
proxy/spdy/SpdyClientSession.cc | 81 +++++++++++++-----------------------
proxy/spdy/SpdyClientSession.h | 11 ++---
3 files changed, 37 insertions(+), 57 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/428c3d58/proxy/spdy/SpdyCallbacks.cc
----------------------------------------------------------------------
diff --git a/proxy/spdy/SpdyCallbacks.cc b/proxy/spdy/SpdyCallbacks.cc
index c31a239..898e49e 100644
--- a/proxy/spdy/SpdyCallbacks.cc
+++ b/proxy/spdy/SpdyCallbacks.cc
@@ -182,7 +182,7 @@ spdy_fetcher_launch(SpdyRequest *req, TSFetchMethod method)
// HTTP content should be dechunked before packed into SPDY.
//
fetch_flags = TS_FETCH_FLAGS_DECHUNK;
- req->fetch_sm = TSFetchCreate(sm->contp, method,
+ req->fetch_sm = TSFetchCreate((TSCont)sm, method,
url.c_str(), req->version.c_str(),
client_addr, fetch_flags);
TSFetchUserDataSet(req->fetch_sm, req);
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/428c3d58/proxy/spdy/SpdyClientSession.cc
----------------------------------------------------------------------
diff --git a/proxy/spdy/SpdyClientSession.cc b/proxy/spdy/SpdyClientSession.cc
index 73cb4e0..43cbcff 100644
--- a/proxy/spdy/SpdyClientSession.cc
+++ b/proxy/spdy/SpdyClientSession.cc
@@ -27,9 +27,6 @@
static ClassAllocator<SpdyClientSession> spdyClientSessionAllocator("spdyClientSessionAllocator");
ClassAllocator<SpdyRequest> spdyRequestAllocator("spdyRequestAllocator");
-static int spdy_main_handler(TSCont contp, TSEvent event, void *edata);
-static int spdy_start_handler(TSCont contp, TSEvent event, void *edata);
-static int spdy_default_handler(TSCont contp, TSEvent event, void *edata);
static int spdy_process_read(TSEvent event, SpdyClientSession *sm);
static int spdy_process_write(TSEvent event, SpdyClientSession *sm);
static int spdy_process_fetch(TSEvent event, SpdyClientSession *sm, void *edata);
@@ -63,6 +60,7 @@ SpdyClientSession::init(NetVConnection * netvc)
atomic_inc(g_sm_cnt);
+ this->mutex = new_ProxyMutex();
this->vc = netvc;
this->req_map.clear();
@@ -85,12 +83,9 @@ SpdyClientSession::init(NetVConnection * netvc)
total_size = 0;
start_time = TShrtime();
- ink_assert(this->contp == NULL);
- this->contp = TSContCreate(spdy_main_handler, TSMutexCreate());
- TSContDataSet(this->contp, this);
-
this->vc->set_inactivity_timeout(HRTIME_SECONDS(SPDY_CFG.accept_no_activity_timeout));
- this->current_handler = &spdy_start_handler;
+ SET_HANDLER(&SpdyClientSession::state_session_start);
+
}
void
@@ -115,15 +110,13 @@ SpdyClientSession::clear()
}
req_map.clear();
+ this->mutex = NULL;
+
if (vc) {
TSVConnClose(reinterpret_cast<TSVConn>(vc));
vc = NULL;
}
- if (contp) {
- TSContDestroy(contp);
- contp = NULL;
- }
if (req_reader) {
TSIOBufferReaderFree(req_reader);
@@ -169,90 +162,76 @@ spdy_sm_create(NetVConnection * netvc, MIOBuffer * iobuf, IOBufferReader * reade
sm->resp_buffer = TSIOBufferCreate();
sm->resp_reader = TSIOBufferReaderAlloc(sm->resp_buffer);
- TSContSchedule(sm->contp, 0, TS_THREAD_POOL_DEFAULT); // schedule now
+ eventProcessor.schedule_imm(sm, ET_NET);
}
-static int
-spdy_main_handler(TSCont contp, TSEvent event, void *edata)
-{
- SpdyClientSession *sm;
- SpdyClientSessionHandler spdy_current_handler;
-
- sm = (SpdyClientSession*)TSContDataGet(contp);
- spdy_current_handler = sm->current_handler;
-
- return (*spdy_current_handler) (contp, event, edata);
-}
-
-static int
-spdy_start_handler(TSCont contp, TSEvent /*event*/, void * /*data*/)
+int
+SpdyClientSession::state_session_start(int /* event */, void * /* edata */)
{
int r;
spdylay_settings_entry entry;
- SpdyClientSession *sm = (SpdyClientSession*)TSContDataGet(contp);
-
- if (TSIOBufferReaderAvail(sm->req_reader) > 0) {
- spdy_process_read(TS_EVENT_VCONN_WRITE_READY, sm);
+ if (TSIOBufferReaderAvail(this->req_reader) > 0) {
+ spdy_process_read(TS_EVENT_VCONN_WRITE_READY, this);
}
- sm->read_vio = (TSVIO)sm->vc->do_io_read(reinterpret_cast<Continuation *>(contp), INT64_MAX, reinterpret_cast<MIOBuffer *>(sm->req_buffer));
- sm->write_vio = (TSVIO)sm->vc->do_io_write(reinterpret_cast<Continuation *>(contp), INT64_MAX, reinterpret_cast<IOBufferReader *>(sm->resp_reader));
+ this->read_vio = (TSVIO)this->vc->do_io_read(this, INT64_MAX, reinterpret_cast<MIOBuffer *>(this->req_buffer));
+ this->write_vio = (TSVIO)this->vc->do_io_write(this, INT64_MAX, reinterpret_cast<IOBufferReader *>(this->resp_reader));
- sm->current_handler = &spdy_default_handler;
+ SET_HANDLER(&SpdyClientSession::state_session_readwrite);
/* send initial settings frame */
entry.settings_id = SPDYLAY_SETTINGS_MAX_CONCURRENT_STREAMS;
entry.value = SPDY_CFG.spdy.max_concurrent_streams;
entry.flags = SPDYLAY_ID_FLAG_SETTINGS_NONE;
- r = spdylay_submit_settings(sm->session, SPDYLAY_FLAG_SETTINGS_NONE, &entry, 1);
+ r = spdylay_submit_settings(this->session, SPDYLAY_FLAG_SETTINGS_NONE, &entry, 1);
TSAssert(r == 0);
- TSVIOReenable(sm->write_vio);
- return 0;
+ TSVIOReenable(this->write_vio);
+ return EVENT_CONT;
}
-static int
-spdy_default_handler(TSCont contp, TSEvent event, void *edata)
+int
+SpdyClientSession::state_session_readwrite(int event, void * edata)
{
int ret = 0;
bool from_fetch = false;
- SpdyClientSession *sm = (SpdyClientSession*)TSContDataGet(contp);
- sm->event = event;
- if (edata == sm->read_vio) {
+ this->event = event;
+
+ if (edata == this->read_vio) {
Debug("spdy", "++++[READ EVENT]");
if (event != TS_EVENT_VCONN_READ_READY &&
event != TS_EVENT_VCONN_READ_COMPLETE) {
ret = -1;
goto out;
}
- ret = spdy_process_read(event, sm);
- } else if (edata == sm->write_vio) {
+ ret = spdy_process_read((TSEvent)event, this);
+ } else if (edata == this->write_vio) {
Debug("spdy", "----[WRITE EVENT]");
if (event != TS_EVENT_VCONN_WRITE_READY &&
event != TS_EVENT_VCONN_WRITE_COMPLETE) {
ret = -1;
goto out;
}
- ret = spdy_process_write(event, sm);
+ ret = spdy_process_write((TSEvent)event, this);
} else {
from_fetch = true;
- ret = spdy_process_fetch(event, sm, edata);
+ ret = spdy_process_fetch((TSEvent)event, this, edata);
}
Debug("spdy-event", "++++SpdyClientSession[%" PRIu64 "], EVENT:%d, ret:%d, nr_pending:%" PRIu64,
- sm->sm_id, event, ret, g_sm_cnt);
+ this->sm_id, event, ret, g_sm_cnt);
out:
if (ret) {
- sm->clear();
- spdyClientSessionAllocator.free(sm);
+ this->clear();
+ spdyClientSessionAllocator.free(this);
} else if (!from_fetch) {
- sm->vc->set_inactivity_timeout(HRTIME_SECONDS(SPDY_CFG.no_activity_timeout_in));
+ this->vc->set_inactivity_timeout(HRTIME_SECONDS(SPDY_CFG.no_activity_timeout_in));
}
- return 0;
+ return EVENT_CONT;
}
static int
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/428c3d58/proxy/spdy/SpdyClientSession.h
----------------------------------------------------------------------
diff --git a/proxy/spdy/SpdyClientSession.h b/proxy/spdy/SpdyClientSession.h
index 00a86b9..ed0f2dd 100644
--- a/proxy/spdy/SpdyClientSession.h
+++ b/proxy/spdy/SpdyClientSession.h
@@ -98,12 +98,12 @@ public:
MD5_CTX recv_md5;
};
-class SpdyClientSession
+class SpdyClientSession : public Continuation
{
public:
- SpdyClientSession() {
+ SpdyClientSession() : Continuation(NULL) {
}
~SpdyClientSession() {
@@ -118,7 +118,6 @@ public:
TSHRTime start_time;
NetVConnection * vc;
- TSCont contp;
TSIOBuffer req_buffer;
TSIOBufferReader req_reader;
@@ -129,12 +128,14 @@ public:
TSVIO read_vio;
TSVIO write_vio;
- SpdyClientSessionHandler current_handler;
-
int event;
spdylay_session *session;
map<int32_t, SpdyRequest*> req_map;
+
+private:
+ int state_session_start(int event, void * edata);
+ int state_session_readwrite(int event, void * edata);
};
void spdy_sm_create(NetVConnection * netvc, MIOBuffer * iobuf, IOBufferReader * reader);