Make the server report monotonic times for deadlines

For very high performance systems, we're going to want to be able to
simply push the value reported from the server down onto clients.

If we report realtime now, then all wrapped languages are going to
assume it, meaning that such a change will be impossible later.
diff --git a/src/core/surface/call.c b/src/core/surface/call.c
index e08273e..1f73f9c 100644
--- a/src/core/surface/call.c
+++ b/src/core/surface/call.c
@@ -1368,7 +1368,8 @@
       l->md = 0;
     }
   }
-  if (gpr_time_cmp(md->deadline, gpr_inf_future(GPR_CLOCK_REALTIME)) != 0) {
+  if (gpr_time_cmp(md->deadline, gpr_inf_future(md->deadline.clock_type)) !=
+      0) {
     set_deadline_alarm(call, md->deadline);
   }
   if (!is_trailing) {
diff --git a/src/core/surface/server.c b/src/core/surface/server.c
index 439452a..a0d4ab3 100644
--- a/src/core/surface/server.c
+++ b/src/core/surface/server.c
@@ -530,6 +530,7 @@
 static void server_on_recv(void *ptr, int success) {
   grpc_call_element *elem = ptr;
   call_data *calld = elem->call_data;
+  gpr_timespec op_deadline;
 
   if (success && !calld->got_initial_metadata) {
     size_t i;
@@ -539,8 +540,9 @@
       grpc_stream_op *op = &ops[i];
       if (op->type != GRPC_OP_METADATA) continue;
       grpc_metadata_batch_filter(&op->data.metadata, server_filter, elem);
-      if (0 != gpr_time_cmp(op->data.metadata.deadline,
-                            gpr_inf_future(GPR_CLOCK_REALTIME))) {
+      op_deadline = op->data.metadata.deadline;
+      if (0 !=
+          gpr_time_cmp(op_deadline, gpr_inf_future(op_deadline.clock_type))) {
         calld->deadline = op->data.metadata.deadline;
       }
       calld->got_initial_metadata = 1;
diff --git a/src/core/transport/chttp2/parsing.c b/src/core/transport/chttp2/parsing.c
index 904b9af..50a2f75 100644
--- a/src/core/transport/chttp2/parsing.c
+++ b/src/core/transport/chttp2/parsing.c
@@ -607,7 +607,7 @@
     }
     grpc_chttp2_incoming_metadata_buffer_set_deadline(
         &stream_parsing->incoming_metadata,
-        gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), *cached_timeout));
+        gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), *cached_timeout));
     GRPC_MDELEM_UNREF(md);
   } else {
     grpc_chttp2_incoming_metadata_buffer_add(&stream_parsing->incoming_metadata,
diff --git a/src/cpp/util/time.cc b/src/cpp/util/time.cc
index a814cad..799c597 100644
--- a/src/cpp/util/time.cc
+++ b/src/cpp/util/time.cc
@@ -79,9 +79,10 @@
 }
 
 system_clock::time_point Timespec2Timepoint(gpr_timespec t) {
-  if (gpr_time_cmp(t, gpr_inf_future(GPR_CLOCK_REALTIME)) == 0) {
+  if (gpr_time_cmp(t, gpr_inf_future(t.clock_type)) == 0) {
     return system_clock::time_point::max();
   }
+  t = gpr_convert_clock_type(t, GPR_CLOCK_REALTIME);
   system_clock::time_point tp;
   tp += duration_cast<system_clock::time_point::duration>(seconds(t.tv_sec));
   tp +=
diff --git a/src/node/ext/timeval.cc b/src/node/ext/timeval.cc
index 60de4d8..bf68513 100644
--- a/src/node/ext/timeval.cc
+++ b/src/node/ext/timeval.cc
@@ -52,6 +52,7 @@
 }
 
 double TimespecToMilliseconds(gpr_timespec timespec) {
+  timespec = gpr_convert_clock_type(timespec, GPR_CLOCK_REALTIME);
   if (gpr_time_cmp(timespec, gpr_inf_future(GPR_CLOCK_REALTIME)) == 0) {
     return std::numeric_limits<double>::infinity();
   } else if (gpr_time_cmp(timespec, gpr_inf_past(GPR_CLOCK_REALTIME)) == 0) {
diff --git a/src/python/src/grpc/_adapter/_c/utility.c b/src/python/src/grpc/_adapter/_c/utility.c
index d9f911a..51f3c9b 100644
--- a/src/python/src/grpc/_adapter/_c/utility.c
+++ b/src/python/src/grpc/_adapter/_c/utility.c
@@ -374,6 +374,7 @@
 }
 
 double pygrpc_cast_gpr_timespec_to_double(gpr_timespec timespec) {
+  timespec = gpr_convert_clock_type(timespec, GPR_CLOCK_REALTIME);
   return timespec.tv_sec + 1e-9*timespec.tv_nsec;
 }
 
diff --git a/src/ruby/ext/grpc/rb_grpc.c b/src/ruby/ext/grpc/rb_grpc.c
index 829f825..65d9c9a 100644
--- a/src/ruby/ext/grpc/rb_grpc.c
+++ b/src/ruby/ext/grpc/rb_grpc.c
@@ -209,10 +209,12 @@
 /* Converts a wrapped time constant to a standard time. */
 static VALUE grpc_rb_time_val_to_time(VALUE self) {
   gpr_timespec *time_const = NULL;
+  gpr_timespec real_time;
   TypedData_Get_Struct(self, gpr_timespec, &grpc_rb_timespec_data_type,
                        time_const);
-  return rb_funcall(rb_cTime, id_at, 2, INT2NUM(time_const->tv_sec),
-                    INT2NUM(time_const->tv_nsec));
+  real_time = gpr_convert_clock_type(*time_const, GPR_CLOCK_REALTIME);
+  return rb_funcall(rb_cTime, id_at, 2, INT2NUM(real_time.tv_sec),
+                    INT2NUM(real_time.tv_nsec));
 }
 
 /* Invokes inspect on the ctime version of the time val. */
diff --git a/src/ruby/ext/grpc/rb_server.c b/src/ruby/ext/grpc/rb_server.c
index e3a0a5a..375a651 100644
--- a/src/ruby/ext/grpc/rb_server.c
+++ b/src/ruby/ext/grpc/rb_server.c
@@ -213,6 +213,7 @@
   grpc_call_error err;
   request_call_stack st;
   VALUE result;
+  gpr_timespec deadline;
   TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s);
   if (s->wrapped == NULL) {
     rb_raise(rb_eRuntimeError, "destroyed!");
@@ -245,15 +246,13 @@
     }
 
     /* build the NewServerRpc struct result */
+    deadline = gpr_convert_clock_type(st.details.deadline, GPR_CLOCK_REALTIME);
     result = rb_struct_new(
-        grpc_rb_sNewServerRpc,
-        rb_str_new2(st.details.method),
+        grpc_rb_sNewServerRpc, rb_str_new2(st.details.method),
         rb_str_new2(st.details.host),
-        rb_funcall(rb_cTime, id_at, 2, INT2NUM(st.details.deadline.tv_sec),
-                   INT2NUM(st.details.deadline.tv_nsec)),
-        grpc_rb_md_ary_to_h(&st.md_ary),
-        grpc_rb_wrap_call(call),
-        NULL);
+        rb_funcall(rb_cTime, id_at, 2, INT2NUM(deadline.tv_sec),
+                   INT2NUM(deadline.tv_nsec)),
+        grpc_rb_md_ary_to_h(&st.md_ary), grpc_rb_wrap_call(call), NULL);
     grpc_request_call_stack_cleanup(&st);
     return result;
   }