You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by ma...@apache.org on 2014/11/24 21:40:35 UTC

trafficserver git commit: TS-3210 fix for 'atscppapi intercept: saved event replay causes crash'

Repository: trafficserver
Updated Branches:
  refs/heads/master 03847a136 -> 57939d166


TS-3210 fix for 'atscppapi intercept: saved event replay causes crash'


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/57939d16
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/57939d16
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/57939d16

Branch: refs/heads/master
Commit: 57939d166280cd8b0e0925f0eb1d0fcc4ce972a2
Parents: 03847a1
Author: Manjesh Nilange <ma...@yahoo.com>
Authored: Mon Nov 24 12:40:10 2014 -0800
Committer: Manjesh Nilange <ma...@yahoo.com>
Committed: Mon Nov 24 12:40:10 2014 -0800

----------------------------------------------------------------------
 lib/atscppapi/src/InterceptPlugin.cc | 44 +++++++++++++++++++++----------
 1 file changed, 30 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/57939d16/lib/atscppapi/src/InterceptPlugin.cc
----------------------------------------------------------------------
diff --git a/lib/atscppapi/src/InterceptPlugin.cc b/lib/atscppapi/src/InterceptPlugin.cc
index fb73602..9503949 100644
--- a/lib/atscppapi/src/InterceptPlugin.cc
+++ b/lib/atscppapi/src/InterceptPlugin.cc
@@ -81,16 +81,18 @@ struct InterceptPlugin::State {
   void *saved_edata_;
 
   TSAction timeout_action_;
+  bool plugin_io_done_;
 
   State(TSCont cont, InterceptPlugin *plugin)
     : cont_(cont), net_vc_(NULL), expected_body_size_(0), num_body_bytes_read_(0), hdr_parsed_(false),
-      hdr_buf_(NULL), hdr_loc_(NULL), num_bytes_written_(0), plugin_(plugin), timeout_action_(NULL) {
+      hdr_buf_(NULL), hdr_loc_(NULL), num_bytes_written_(0), plugin_(plugin), timeout_action_(NULL),
+      plugin_io_done_(false) {
     plugin_mutex_ = plugin->getMutex();
     http_parser_ = TSHttpParserCreate();
   }
-
+  
   ~State() {
-    TSHttpParserDestroy(http_parser_);
+    TSHttpParserDestroy(http_parser_); 
     if (hdr_loc_) {
       TSHandleMLocRelease(hdr_buf_, TS_NULL_MLOC, hdr_loc_);
     }
@@ -127,7 +129,7 @@ InterceptPlugin::~InterceptPlugin() {
     state_->plugin_ = NULL; // prevent callback from invoking plugin
   }
   else { // safe to cleanup
-    LOG_DEBUG("Normal shutdown");
+    LOG_DEBUG("Normal cleanup");
     delete state_;
   }
 }
@@ -166,6 +168,7 @@ bool InterceptPlugin::setOutputComplete() {
   }
   TSVIONBytesSet(state_->output_.vio_, state_->num_bytes_written_);
   TSVIOReenable(state_->output_.vio_);
+  state_->plugin_io_done_ = true;
   LOG_DEBUG("Response complete");
   return true;
 }
@@ -180,7 +183,7 @@ bool InterceptPlugin::doRead() {
     LOG_ERROR("Error while getting number of bytes available");
     return false;
   }
-
+  
   int consumed = 0; // consumed is used to update the input buffers
   if (avail > 0) {
     int64_t num_body_bytes_in_block;
@@ -233,7 +236,7 @@ bool InterceptPlugin::doRead() {
   }
   LOG_DEBUG("Consumed %d bytes from input vio", consumed);
   TSIOBufferReaderConsume(state_->input_.reader_, consumed);
-
+  
   // Modify the input VIO to reflect how much data we've completed.
   TSVIONDoneSet(state_->input_.vio_, TSVIONDoneGet(state_->input_.vio_) + consumed);
 
@@ -274,11 +277,11 @@ void InterceptPlugin::handleEvent(int abstract_event, void *edata) {
     break;
 
   case TS_EVENT_VCONN_WRITE_READY: // nothing to do
-    LOG_DEBUG("Got write ready");
+    LOG_DEBUG("Got write ready"); 
     break;
 
   case TS_EVENT_VCONN_READ_READY:
-    LOG_DEBUG("Handling read ready");
+    LOG_DEBUG("Handling read ready");  
     if (doRead()) {
       break;
     }
@@ -297,7 +300,6 @@ void InterceptPlugin::handleEvent(int abstract_event, void *edata) {
     }
     LOG_DEBUG("Shutting down intercept");
     destroyCont(state_);
-    state_->cont_ = NULL;
     break;
 
   default:
@@ -307,7 +309,12 @@ void InterceptPlugin::handleEvent(int abstract_event, void *edata) {
 
 namespace {
 
-int handleEvents(TSCont cont, TSEvent event, void *edata) {
+int handleEvents(TSCont cont, TSEvent pristine_event, void *pristine_edata) {
+
+  // Separating pristine and mutable data helps debugging
+  TSEvent event = pristine_event;
+  void *edata = pristine_edata;
+
   InterceptPlugin::State *state = static_cast<InterceptPlugin::State *>(TSContDataGet(cont));
   ScopedSharedMutexTryLock scopedTryLock(state->plugin_mutex_);
   if (!scopedTryLock.hasLock()) {
@@ -319,10 +326,16 @@ int handleEvents(TSCont cont, TSEvent event, void *edata) {
     state->timeout_action_ = TSContSchedule(cont, 1, TS_THREAD_POOL_DEFAULT);
     return 0;
   }
-  if (event == TS_EVENT_TIMEOUT) {
+  if (event == TS_EVENT_TIMEOUT) { // we have a saved event to restore
     state->timeout_action_ = NULL;
-    event = state->saved_event_; // restore saved event
-    edata = state->saved_edata_;
+    if (state->plugin_io_done_) { // plugin is done, so can't send it saved event
+      event = TS_EVENT_VCONN_EOS; // fake completion
+      edata = NULL;
+    }
+    else {
+      event = state->saved_event_;
+      edata = state->saved_edata_;
+    }
   }
   if (state->plugin_) {
     utils::internal::dispatchInterceptEvent(state->plugin_, event, edata);
@@ -343,7 +356,10 @@ void destroyCont(InterceptPlugin::State *state) {
     TSVConnClose(state->net_vc_);
     state->net_vc_ = NULL;
   }
-  TSContDestroy(state->cont_);
+  if (!state->timeout_action_) {
+    TSContDestroy(state->cont_);
+    state->cont_ = NULL;
+  }
 }
 
 }