Merge pull request #14801 from fengli79/master

Release the GIL when calling grpc_call_start_batch.
diff --git a/examples/cpp/route_guide/route_guide_server.cc b/examples/cpp/route_guide/route_guide_server.cc
index 24a4184..5867c16 100644
--- a/examples/cpp/route_guide/route_guide_server.cc
+++ b/examples/cpp/route_guide/route_guide_server.cc
@@ -51,6 +51,7 @@
   return num * 3.1415926 /180;
 }
 
+// The formula is based on http://mathforum.org/library/drmath/view/51879.html
 float GetDistance(const Point& start, const Point& end) {
   const float kCoordFactor = 10000000.0;
   float lat_1 = start.latitude() / kCoordFactor;
diff --git a/examples/csharp/route_guide/RouteGuide/RouteGuideUtil.cs b/examples/csharp/route_guide/RouteGuide/RouteGuideUtil.cs
index 66c4a94..f9af190 100644
--- a/examples/csharp/route_guide/RouteGuide/RouteGuideUtil.cs
+++ b/examples/csharp/route_guide/RouteGuide/RouteGuideUtil.cs
@@ -52,26 +52,23 @@
 
         /// <summary>
         /// Calculate the distance between two points using the "haversine" formula.
-        /// This code was taken from http://www.movable-type.co.uk/scripts/latlong.html.
+        /// The formula is based on http://mathforum.org/library/drmath/view/51879.html
         /// </summary>
         /// <param name="start">the starting point</param>
         /// <param name="end">the end point</param>
         /// <returns>the distance between the points in meters</returns>
         public static double GetDistance(this Point start, Point end)
         {
-            double lat1 = start.GetLatitude();
-            double lat2 = end.GetLatitude();
-            double lon1 = start.GetLongitude();
-            double lon2 = end.GetLongitude();
-            int r = 6371000; // metres
-            double phi1 = ToRadians(lat1);
-            double phi2 = ToRadians(lat2);
-            double deltaPhi = ToRadians(lat2 - lat1);
-            double deltaLambda = ToRadians(lon2 - lon1);
+            int r = 6371000;  // earth radius in metres
+            double lat1 = ToRadians(start.GetLatitude());
+            double lat2 = ToRadians(end.GetLatitude());
+            double lon1 = ToRadians(start.GetLongitude());
+            double lon2 = ToRadians(end.GetLongitude());
+            double deltalat = lat2 - lat1;
+            double deltalon = lon2 - lon1;
 
-            double a = Math.Sin(deltaPhi / 2) * Math.Sin(deltaPhi / 2) + Math.Cos(phi1) * Math.Cos(phi2) * Math.Sin(deltaLambda / 2) * Math.Sin(deltaLambda / 2);
+            double a = Math.Sin(deltalat / 2) * Math.Sin(deltalat / 2) + Math.Cos(lat1) * Math.Cos(lat2) * Math.Sin(deltalon / 2) * Math.Sin(deltalon / 2);
             double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
-
             return r * c;
         }
 
diff --git a/examples/node/dynamic_codegen/route_guide/route_guide_server.js b/examples/node/dynamic_codegen/route_guide/route_guide_server.js
index ab537ff..f9028e8 100644
--- a/examples/node/dynamic_codegen/route_guide/route_guide_server.js
+++ b/examples/node/dynamic_codegen/route_guide/route_guide_server.js
@@ -103,7 +103,7 @@
 
 /**
  * Calculate the distance between two points using the "haversine" formula.
- * This code was taken from http://www.movable-type.co.uk/scripts/latlong.html.
+ * The formula is based on http://mathforum.org/library/drmath/view/51879.html.
  * @param start The starting point
  * @param end The end point
  * @return The distance between the points in meters
@@ -112,21 +112,18 @@
   function toRadians(num) {
     return num * Math.PI / 180;
   }
-  var lat1 = start.latitude / COORD_FACTOR;
-  var lat2 = end.latitude / COORD_FACTOR;
-  var lon1 = start.longitude / COORD_FACTOR;
-  var lon2 = end.longitude / COORD_FACTOR;
-  var R = 6371000; // metres
-  var φ1 = toRadians(lat1);
-  var φ2 = toRadians(lat2);
-  var Δφ = toRadians(lat2-lat1);
-  var Δλ = toRadians(lon2-lon1);
+  var R = 6371000;  // earth radius in metres
+  var lat1 = toRadians(start.latitude / COORD_FACTOR);
+  var lat2 = toRadians(end.latitude / COORD_FACTOR);
+  var lon1 = toRadians(start.longitude / COORD_FACTOR);
+  var lon2 = toRadians(end.longitude / COORD_FACTOR);
 
-  var a = Math.sin(Δφ/2) * Math.sin(Δφ/2) +
-      Math.cos(φ1) * Math.cos(φ2) *
-      Math.sin(Δλ/2) * Math.sin(Δλ/2);
+  var deltalat = lat2-lat1;
+  var deltalon = lon2-lon1;
+  var a = Math.sin(deltalat/2) * Math.sin(deltalat/2) +
+      Math.cos(lat1) * Math.cos(lat2) *
+      Math.sin(dlon/2) * Math.sin(dlon/2);
   var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
-
   return R * c;
 }
 
diff --git a/examples/node/static_codegen/route_guide/route_guide_server.js b/examples/node/static_codegen/route_guide/route_guide_server.js
index ef00bbb..eecac62 100644
--- a/examples/node/static_codegen/route_guide/route_guide_server.js
+++ b/examples/node/static_codegen/route_guide/route_guide_server.js
@@ -102,7 +102,7 @@
 
 /**
  * Calculate the distance between two points using the "haversine" formula.
- * This code was taken from http://www.movable-type.co.uk/scripts/latlong.html.
+ * The formula is based on http://mathforum.org/library/drmath/view/51879.html.
  * @param start The starting point
  * @param end The end point
  * @return The distance between the points in meters
@@ -111,21 +111,18 @@
   function toRadians(num) {
     return num * Math.PI / 180;
   }
-  var lat1 = start.getLatitude() / COORD_FACTOR;
-  var lat2 = end.getLatitude() / COORD_FACTOR;
-  var lon1 = start.getLongitude() / COORD_FACTOR;
-  var lon2 = end.getLongitude() / COORD_FACTOR;
-  var R = 6371000; // metres
-  var φ1 = toRadians(lat1);
-  var φ2 = toRadians(lat2);
-  var Δφ = toRadians(lat2-lat1);
-  var Δλ = toRadians(lon2-lon1);
+  var R = 6371000;  // earth radius in metres
+  var lat1 = toRadians(start.getLatitude() / COORD_FACTOR);
+  var lat2 = toRadians(end.getLatitude() / COORD_FACTOR);
+  var lon1 = toRadians(start.getLongitude() / COORD_FACTOR);
+  var lon2 = toRadians(end.getLongitude() / COORD_FACTOR);
 
-  var a = Math.sin(Δφ/2) * Math.sin(Δφ/2) +
-      Math.cos(φ1) * Math.cos(φ2) *
-      Math.sin(Δλ/2) * Math.sin(Δλ/2);
+  var deltalat = lat2-lat1;
+  var deltalon = lon2-lon1;
+  var a = Math.sin(deltalat/2) * Math.sin(deltalat/2) +
+      Math.cos(lat1) * Math.cos(lat2) *
+      Math.sin(deltalon/2) * Math.sin(deltalon/2);
   var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
-
   return R * c;
 }
 
diff --git a/examples/python/route_guide/route_guide_server.py b/examples/python/route_guide/route_guide_server.py
index f10008f..1969fdd 100644
--- a/examples/python/route_guide/route_guide_server.py
+++ b/examples/python/route_guide/route_guide_server.py
@@ -46,6 +46,7 @@
     delta_lat_rad = math.radians(lat_2 - lat_1)
     delta_lon_rad = math.radians(lon_2 - lon_1)
 
+    # Formula is based on http://mathforum.org/library/drmath/view/51879.html
     a = (pow(math.sin(delta_lat_rad / 2), 2) +
          (math.cos(lat_rad_1) * math.cos(lat_rad_2) * pow(
              math.sin(delta_lon_rad / 2), 2)))
diff --git a/examples/ruby/route_guide/route_guide_server.rb b/examples/ruby/route_guide/route_guide_server.rb
index 8ea07a2..5eb268b 100755
--- a/examples/ruby/route_guide/route_guide_server.rb
+++ b/examples/ruby/route_guide/route_guide_server.rb
@@ -32,19 +32,18 @@
 RADIUS = 637_100
 
 # Determines the distance between two points.
+# The formula is based on http://mathforum.org/library/drmath/view/51879.html.
 def calculate_distance(point_a, point_b)
   to_radians = proc { |x| x * Math::PI / 180 }
-  lat_a = point_a.latitude / COORD_FACTOR
-  lat_b = point_b.latitude / COORD_FACTOR
-  long_a = point_a.longitude / COORD_FACTOR
-  long_b = point_b.longitude / COORD_FACTOR
-  φ1 = to_radians.call(lat_a)
-  φ2 = to_radians.call(lat_b)
-  Δφ = to_radians.call(lat_a - lat_b)
-  Δλ = to_radians.call(long_a - long_b)
-  a = Math.sin(Δφ / 2)**2 +
-      Math.cos(φ1) * Math.cos(φ2) +
-      Math.sin(Δλ / 2)**2
+  lat_a = to_radians.call(point_a.latitude / COORD_FACTOR)
+  lat_b = to_radians.call(point_b.latitude / COORD_FACTOR)
+  lon_a = to_radians.call(point_a.longitude / COORD_FACTOR)
+  lon_b = to_radians.call(point_b.longitude / COORD_FACTOR)
+  delta_lat = lat_a - lat_b
+  delta_lon = lon_a - lon_b
+  a = Math.sin(delta_lat / 2)**2 +
+      Math.cos(lat_a) * Math.cos(lat_b) +
+      Math.sin(delta_lon / 2)**2
   (2 * RADIUS *  Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))).to_i
 end
 
diff --git a/include/grpcpp/impl/codegen/call.h b/include/grpcpp/impl/codegen/call.h
index 3b0fd60..28cc4a9 100644
--- a/include/grpcpp/impl/codegen/call.h
+++ b/include/grpcpp/impl/codegen/call.h
@@ -656,21 +656,6 @@
   grpc_call* call_;
 };
 
-/// A CallOpSet that does not post completions to the completion queue.
-///
-/// Allows hiding some completions that the C core must generate from
-/// C++ users.
-template <class Op1 = CallNoOp<1>, class Op2 = CallNoOp<2>,
-          class Op3 = CallNoOp<3>, class Op4 = CallNoOp<4>,
-          class Op5 = CallNoOp<5>, class Op6 = CallNoOp<6>>
-class SneakyCallOpSet : public CallOpSet<Op1, Op2, Op3, Op4, Op5, Op6> {
- public:
-  bool FinalizeResult(void** tag, bool* status) override {
-    typedef CallOpSet<Op1, Op2, Op3, Op4, Op5, Op6> Base;
-    return Base::FinalizeResult(tag, status) && false;
-  }
-};
-
 /// Straightforward wrapping of the C call object
 class Call final {
  public:
diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h
index e88e796..81c3907 100644
--- a/include/grpcpp/server.h
+++ b/include/grpcpp/server.h
@@ -162,8 +162,8 @@
   friend class ServerInitializer;
 
   class SyncRequest;
-  class AsyncRequest;
-  class ShutdownRequest;
+  class UnimplementedAsyncRequest;
+  class UnimplementedAsyncResponse;
 
   /// SyncRequestThreadManager is an implementation of ThreadManager. This class
   /// is responsible for polling for incoming RPCs and calling the RPC handlers.
@@ -171,10 +171,6 @@
   /// interface)
   class SyncRequestThreadManager;
 
-  class UnimplementedAsyncRequestContext;
-  class UnimplementedAsyncRequest;
-  class UnimplementedAsyncResponse;
-
   /// Register a generic service. This call does not take ownership of the
   /// service. The service must exist for the lifetime of the Server instance.
   void RegisterAsyncGenericService(AsyncGenericService* service) override;
diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc
index 760aaa4..391ca44 100644
--- a/src/cpp/server/server_cc.cc
+++ b/src/cpp/server/server_cc.cc
@@ -45,6 +45,7 @@
 #include "src/cpp/thread_manager/thread_manager.h"
 
 namespace grpc {
+namespace {
 
 class DefaultGlobalCallbacks final : public Server::GlobalCallbacks {
  public:
@@ -53,16 +54,29 @@
   void PostSynchronousRequest(ServerContext* context) override {}
 };
 
-static std::shared_ptr<Server::GlobalCallbacks> g_callbacks = nullptr;
-static gpr_once g_once_init_callbacks = GPR_ONCE_INIT;
+std::shared_ptr<Server::GlobalCallbacks> g_callbacks = nullptr;
+gpr_once g_once_init_callbacks = GPR_ONCE_INIT;
 
-static void InitGlobalCallbacks() {
+void InitGlobalCallbacks() {
   if (!g_callbacks) {
     g_callbacks.reset(new DefaultGlobalCallbacks());
   }
 }
 
-class Server::UnimplementedAsyncRequestContext {
+class ShutdownTag : public internal::CompletionQueueTag {
+ public:
+  bool FinalizeResult(void** tag, bool* status) { return false; }
+};
+
+class DummyTag : public internal::CompletionQueueTag {
+ public:
+  bool FinalizeResult(void** tag, bool* status) {
+    *status = true;
+    return true;
+  }
+};
+
+class UnimplementedAsyncRequestContext {
  protected:
   UnimplementedAsyncRequestContext() : generic_stream_(&server_context_) {}
 
@@ -70,8 +84,14 @@
   GenericServerAsyncReaderWriter generic_stream_;
 };
 
+}  // namespace
+
+/// Use private inheritance rather than composition only to establish order
+/// of construction, since the public base class should be constructed after the
+/// elements belonging to the private base class are constructed. This is not
+/// possible using true composition.
 class Server::UnimplementedAsyncRequest final
-    : public UnimplementedAsyncRequestContext,
+    : private UnimplementedAsyncRequestContext,
       public GenericAsyncRequest {
  public:
   UnimplementedAsyncRequest(Server* server, ServerCompletionQueue* cq)
@@ -90,38 +110,27 @@
   ServerCompletionQueue* const cq_;
 };
 
-typedef internal::SneakyCallOpSet<internal::CallOpSendInitialMetadata,
-                                  internal::CallOpServerSendStatus>
-    UnimplementedAsyncResponseOp;
+/// UnimplementedAsyncResponse should not post user-visible completions to the
+/// C++ completion queue, but is generated as a CQ event by the core
 class Server::UnimplementedAsyncResponse final
-    : public UnimplementedAsyncResponseOp {
+    : public internal::CallOpSet<internal::CallOpSendInitialMetadata,
+                                 internal::CallOpServerSendStatus> {
  public:
   UnimplementedAsyncResponse(UnimplementedAsyncRequest* request);
   ~UnimplementedAsyncResponse() { delete request_; }
 
   bool FinalizeResult(void** tag, bool* status) override {
-    bool r = UnimplementedAsyncResponseOp::FinalizeResult(tag, status);
+    internal::CallOpSet<
+        internal::CallOpSendInitialMetadata,
+        internal::CallOpServerSendStatus>::FinalizeResult(tag, status);
     delete this;
-    return r;
+    return false;
   }
 
  private:
   UnimplementedAsyncRequest* const request_;
 };
 
-class ShutdownTag : public internal::CompletionQueueTag {
- public:
-  bool FinalizeResult(void** tag, bool* status) { return false; }
-};
-
-class DummyTag : public internal::CompletionQueueTag {
- public:
-  bool FinalizeResult(void** tag, bool* status) {
-    *status = true;
-    return true;
-  }
-};
-
 class Server::SyncRequest final : public internal::CompletionQueueTag {
  public:
   SyncRequest(internal::RpcServiceMethod* method, void* tag)