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/test/cpp/src/TestServer.cpp b/test/cpp/src/TestServer.cpp
index d6063ac..18bdc54 100644
--- a/test/cpp/src/TestServer.cpp
+++ b/test/cpp/src/TestServer.cpp
@@ -287,6 +287,39 @@
   }
 };
 
+
+class TestProcessorEventHandler : public TProcessorEventHandler {
+  virtual void* getContext(const char* fn_name) {
+    return new std::string(fn_name);
+  }
+  virtual void freeContext(void* ctx, const char* fn_name) {
+    delete static_cast<std::string*>(ctx);
+  }
+  virtual void preRead(void* ctx, const char* fn_name) {
+    communicate("preRead", ctx, fn_name);
+  }
+  virtual void postRead(void* ctx, const char* fn_name) {
+    communicate("postRead", ctx, fn_name);
+  }
+  virtual void preWrite(void* ctx, const char* fn_name) {
+    communicate("preWrite", ctx, fn_name);
+  }
+  virtual void postWrite(void* ctx, const char* fn_name) {
+    communicate("postWrite", ctx, fn_name);
+  }
+  virtual void asyncComplete(void* ctx, const char* fn_name) {
+    communicate("asyncComplete", ctx, fn_name);
+  }
+  virtual void handlerError(void* ctx, const char* fn_name) {
+    communicate("handlerError", ctx, fn_name);
+  }
+
+  void communicate(const char* event, void* ctx, const char* fn_name) {
+    std::cout << event << ": " << *static_cast<std::string*>(ctx) << " = " << fn_name << std::endl;
+  }
+};
+
+
 int main(int argc, char **argv) {
 
   int port = 9090;
@@ -297,7 +330,7 @@
   ostringstream usage;
 
   usage <<
-    argv[0] << " [--port=<port number>] [--server-type=<server-type>] [--protocol-type=<protocol-type>] [--workers=<worker-count>]" << endl <<
+    argv[0] << " [--port=<port number>] [--server-type=<server-type>] [--protocol-type=<protocol-type>] [--workers=<worker-count>] [--processor-events]" << endl <<
 
     "\t\tserver-type\t\ttype of server, \"simple\", \"thread-pool\", \"threaded\", or \"nonblocking\".  Default is " << serverType << endl <<
 
@@ -365,6 +398,12 @@
 
   shared_ptr<ThriftTestProcessor> testProcessor(new ThriftTestProcessor(testHandler));
 
+
+  if (!args["processor-events"].empty()) {
+    testProcessor->setEventHandler(shared_ptr<TProcessorEventHandler>(
+          new TestProcessorEventHandler()));
+  }
+
   // Transport
   shared_ptr<TServerSocket> serverSocket(new TServerSocket(port));