THRIFT-928. cpp: Processor-level event callbacks

- Add a TProcessorEventHandler callback interface.
- Add methods to TProcessor to hold an instance of the interface.
- Add code to the compiler to make the processor call callbacks at key points.
- Add an optional processor event handler to the test server.

git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@1005126 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/TProcessor.h b/lib/cpp/src/TProcessor.h
index f2d5279..22c10f1 100644
--- a/lib/cpp/src/TProcessor.h
+++ b/lib/cpp/src/TProcessor.h
@@ -27,6 +27,65 @@
 namespace apache { namespace thrift {
 
 /**
+ * Virtual interface class that can handle events from the processor. To
+ * use this you should subclass it and implement the methods that you care
+ * about. Your subclass can also store local data that you may care about,
+ * such as additional "arguments" to these methods (stored in the object
+ * instance's state).
+ */
+class TProcessorEventHandler {
+ public:
+
+  virtual ~TProcessorEventHandler() {}
+
+  /**
+   * Called before calling other callback methods.
+   * Expected to return some sort of context object.
+   * The return value is passed to all other callbacks
+   * for that function invocation.
+   */
+  virtual void* getContext(const char* fn_name) { return NULL; }
+
+  /**
+   * Expected to free resources associated with a context.
+   */
+  virtual void freeContext(void* ctx, const char* fn_name) { }
+
+  /**
+   * Called before reading arguments.
+   */
+  virtual void preRead(void* ctx, const char* fn_name) {}
+
+  /**
+   * Called between reading arguments and calling the handler.
+   */
+  virtual void postRead(void* ctx, const char* fn_name) {}
+
+  /**
+   * Called between calling the handler and writing the response.
+   */
+  virtual void preWrite(void* ctx, const char* fn_name) {}
+
+  /**
+   * Called after writing the response.
+   */
+  virtual void postWrite(void* ctx, const char* fn_name) {}
+
+  /**
+   * Called when an async function call completes successfully.
+   */
+  virtual void asyncComplete(void* ctx, const char* fn_name) {}
+
+  /**
+   * Called if the handler throws an undeclared exception.
+   */
+  virtual void handlerError(void* ctx, const char* fn_name) {}
+
+ protected:
+  TProcessorEventHandler() {}
+};
+
+/**
  * A processor is a generic object that acts upon two streams of data, one
  * an input and the other an output. The definition of this object is loose,
  * though the typical case is for some sort of server that either generates
@@ -44,8 +103,18 @@
     return process(io, io);
   }
 
+  boost::shared_ptr<TProcessorEventHandler> getEventHandler() {
+    return eventHandler_;
+  }
+
+  void setEventHandler(boost::shared_ptr<TProcessorEventHandler> eventHandler) {
+    eventHandler_ = eventHandler;
+  }
+
  protected:
   TProcessor() {}
+
+  boost::shared_ptr<TProcessorEventHandler> eventHandler_;
 };
 
 }} // apache::thrift