From 88086373db8c1d933f40d0275c4b9c8a8c9b9723 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 10 Dec 2015 10:54:12 -0800 Subject: make gpr_timespec platform agnostic --- src/core/iomgr/timer.c | 4 +- src/core/profiling/basic_timers.c | 7 +- src/core/security/credentials.c | 4 +- src/core/statistics/window_stats.c | 2 +- src/core/support/log_linux.c | 4 +- src/core/support/log_posix.c | 4 +- src/core/support/log_win32.c | 4 +- src/core/support/time.c | 64 ++++++--------- src/core/support/time_posix.c | 17 +++- src/core/support/time_precise.c | 4 +- src/core/support/time_win32.c | 6 +- src/core/surface/channel.c | 8 +- src/core/surface/channel_connectivity.c | 6 +- src/core/surface/completion_queue.c | 8 +- src/core/transport/chttp2/timeout_encoding.c | 10 +-- src/core/transport/transport_op_string.c | 4 +- src/cpp/util/time.cc | 8 +- .../Grpc.Core.Tests/Internal/TimespecTest.cs | 91 +++++++--------------- src/csharp/Grpc.Core/Internal/Timespec.cs | 23 ++---- src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd | 6 +- src/ruby/ext/grpc/rb_grpc.c | 4 +- 21 files changed, 125 insertions(+), 163 deletions(-) (limited to 'src') diff --git a/src/core/iomgr/timer.c b/src/core/iomgr/timer.c index 66fafe75ad..c0e3175c4c 100644 --- a/src/core/iomgr/timer.c +++ b/src/core/iomgr/timer.c @@ -126,8 +126,8 @@ static double ts_to_dbl(gpr_timespec ts) { static gpr_timespec dbl_to_ts(double d) { gpr_timespec ts; - ts.tv_sec = (time_t)d; - ts.tv_nsec = (int)(1e9 * (d - (double)ts.tv_sec)); + ts.tv_sec = (gpr_int64)d; + ts.tv_nsec = (gpr_int32)(1e9 * (d - (double)ts.tv_sec)); ts.clock_type = GPR_TIMESPAN; return ts; } diff --git a/src/core/profiling/basic_timers.c b/src/core/profiling/basic_timers.c index f0fce7858d..eedd387ebc 100644 --- a/src/core/profiling/basic_timers.c +++ b/src/core/profiling/basic_timers.c @@ -141,10 +141,11 @@ static void write_log(gpr_timer_log *log) { entry->tm = gpr_time_0(entry->tm.clock_type); } fprintf(output_file, - "{\"t\": %ld.%09d, \"thd\": \"%d\", \"type\": \"%c\", \"tag\": " + "{\"t\": %lld.%09d, \"thd\": \"%d\", \"type\": \"%c\", \"tag\": " "\"%s\", \"file\": \"%s\", \"line\": %d, \"imp\": %d}\n", - entry->tm.tv_sec, entry->tm.tv_nsec, entry->thd, entry->type, - entry->tagstr, entry->file, entry->line, entry->important); + (long long)entry->tm.tv_sec, (int)entry->tm.tv_nsec, entry->thd, + entry->type, entry->tagstr, entry->file, entry->line, + entry->important); } } diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c index 543c75044b..cbaec7d050 100644 --- a/src/core/security/credentials.c +++ b/src/core/security/credentials.c @@ -511,9 +511,9 @@ grpc_call_credentials *grpc_service_account_jwt_access_credentials_create( "grpc_service_account_jwt_access_credentials_create(" "json_key=%s, " "token_lifetime=" - "gpr_timespec { tv_sec: %ld, tv_nsec: %d, clock_type: %d }, " + "gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, " "reserved=%p)", - 5, (json_key, (long)token_lifetime.tv_sec, token_lifetime.tv_nsec, + 5, (json_key, (long long)token_lifetime.tv_sec, (int)token_lifetime.tv_nsec, (int)token_lifetime.clock_type, reserved)); GPR_ASSERT(reserved == NULL); return grpc_service_account_jwt_access_credentials_create_from_auth_json_key( diff --git a/src/core/statistics/window_stats.c b/src/core/statistics/window_stats.c index 4d0d3cca4a..e744006bb5 100644 --- a/src/core/statistics/window_stats.c +++ b/src/core/statistics/window_stats.c @@ -94,7 +94,7 @@ static gpr_int64 timespec_to_ns(const gpr_timespec ts) { if (ts.tv_sec > max_seconds) { return GPR_INT64_MAX - 1; } - return (gpr_int64)ts.tv_sec * GPR_NS_PER_SEC + ts.tv_nsec; + return ts.tv_sec * GPR_NS_PER_SEC + ts.tv_nsec; } static void cws_initialize_statistic(void *statistic, diff --git a/src/core/support/log_linux.c b/src/core/support/log_linux.c index 02f64d8b7e..d66b7a3cc0 100644 --- a/src/core/support/log_linux.c +++ b/src/core/support/log_linux.c @@ -76,16 +76,18 @@ void gpr_default_log(gpr_log_func_args *args) { char *prefix; const char *display_file; char time_buffer[64]; + time_t timer; gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME); struct tm tm; + timer = (time_t)now.tv_sec; final_slash = strrchr(args->file, '/'); if (final_slash == NULL) display_file = args->file; else display_file = final_slash + 1; - if (!localtime_r(&now.tv_sec, &tm)) { + if (!localtime_r(&timer, &tm)) { strcpy(time_buffer, "error:localtime"); } else if (0 == strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) { diff --git a/src/core/support/log_posix.c b/src/core/support/log_posix.c index 8b050dbee7..8986254e4e 100644 --- a/src/core/support/log_posix.c +++ b/src/core/support/log_posix.c @@ -75,16 +75,18 @@ void gpr_default_log(gpr_log_func_args *args) { char *final_slash; const char *display_file; char time_buffer[64]; + time_t timer; gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME); struct tm tm; + timer = (time_t)now.tv_sec; final_slash = strrchr(args->file, '/'); if (final_slash == NULL) display_file = args->file; else display_file = final_slash + 1; - if (!localtime_r(&now.tv_sec, &tm)) { + if (!localtime_r(&timer, &tm)) { strcpy(time_buffer, "error:localtime"); } else if (0 == strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) { diff --git a/src/core/support/log_win32.c b/src/core/support/log_win32.c index b68239f8f5..28e7768f80 100644 --- a/src/core/support/log_win32.c +++ b/src/core/support/log_win32.c @@ -84,16 +84,18 @@ void gpr_default_log(gpr_log_func_args *args) { char *final_slash; const char *display_file; char time_buffer[64]; + time_t timer; gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME); struct tm tm; + timer = (time_t)now.tv_sec; final_slash = strrchr(args->file, '\\'); if (final_slash == NULL) display_file = args->file; else display_file = final_slash + 1; - if (localtime_s(&tm, &now.tv_sec)) { + if (localtime_s(&tm, &timer)) { strcpy(time_buffer, "error:localtime"); } else if (0 == strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) { diff --git a/src/core/support/time.c b/src/core/support/time.c index 929adac918..197fa9ad44 100644 --- a/src/core/support/time.c +++ b/src/core/support/time.c @@ -56,22 +56,6 @@ gpr_timespec gpr_time_max(gpr_timespec a, gpr_timespec b) { return gpr_time_cmp(a, b) > 0 ? a : b; } -/* There's no standard TIME_T_MIN and TIME_T_MAX, so we construct them. The - following assumes that signed types are two's-complement and that bytes are - 8 bits. */ - -/* The top bit of integral type t. */ -#define TOP_BIT_OF_TYPE(t) (((gpr_uintmax)1) << ((8 * sizeof(t)) - 1)) - -/* Return whether integral type t is signed. */ -#define TYPE_IS_SIGNED(t) (((t)1) > (t) ~(t)0) - -/* The minimum and maximum value of integral type t. */ -#define TYPE_MIN(t) ((t)(TYPE_IS_SIGNED(t) ? TOP_BIT_OF_TYPE(t) : 0)) -#define TYPE_MAX(t) \ - ((t)(TYPE_IS_SIGNED(t) ? (TOP_BIT_OF_TYPE(t) - 1) \ - : ((TOP_BIT_OF_TYPE(t) - 1) << 1) + 1)) - gpr_timespec gpr_time_0(gpr_clock_type type) { gpr_timespec out; out.tv_sec = 0; @@ -82,7 +66,7 @@ gpr_timespec gpr_time_0(gpr_clock_type type) { gpr_timespec gpr_inf_future(gpr_clock_type type) { gpr_timespec out; - out.tv_sec = TYPE_MAX(time_t); + out.tv_sec = INT64_MAX; out.tv_nsec = 0; out.clock_type = type; return out; @@ -90,7 +74,7 @@ gpr_timespec gpr_inf_future(gpr_clock_type type) { gpr_timespec gpr_inf_past(gpr_clock_type type) { gpr_timespec out; - out.tv_sec = TYPE_MIN(time_t); + out.tv_sec = INT64_MIN; out.tv_nsec = 0; out.clock_type = type; return out; @@ -108,11 +92,11 @@ gpr_timespec gpr_time_from_nanos(long ns, gpr_clock_type type) { result = gpr_inf_past(type); } else if (ns >= 0) { result.tv_sec = ns / GPR_NS_PER_SEC; - result.tv_nsec = (int)(ns - result.tv_sec * GPR_NS_PER_SEC); + result.tv_nsec = (gpr_int32)(ns - result.tv_sec * GPR_NS_PER_SEC); } else { /* Calculation carefully formulated to avoid any possible under/overflow. */ result.tv_sec = (-(999999999 - (ns + GPR_NS_PER_SEC)) / GPR_NS_PER_SEC) - 1; - result.tv_nsec = (int)(ns - result.tv_sec * GPR_NS_PER_SEC); + result.tv_nsec = (gpr_int32)(ns - result.tv_sec * GPR_NS_PER_SEC); } return result; } @@ -126,11 +110,11 @@ gpr_timespec gpr_time_from_micros(long us, gpr_clock_type type) { result = gpr_inf_past(type); } else if (us >= 0) { result.tv_sec = us / 1000000; - result.tv_nsec = (int)((us - result.tv_sec * 1000000) * 1000); + result.tv_nsec = (gpr_int32)((us - result.tv_sec * 1000000) * 1000); } else { /* Calculation carefully formulated to avoid any possible under/overflow. */ result.tv_sec = (-(999999 - (us + 1000000)) / 1000000) - 1; - result.tv_nsec = (int)((us - result.tv_sec * 1000000) * 1000); + result.tv_nsec = (gpr_int32)((us - result.tv_sec * 1000000) * 1000); } return result; } @@ -144,11 +128,11 @@ gpr_timespec gpr_time_from_millis(long ms, gpr_clock_type type) { result = gpr_inf_past(type); } else if (ms >= 0) { result.tv_sec = ms / 1000; - result.tv_nsec = (int)((ms - result.tv_sec * 1000) * 1000000); + result.tv_nsec = (gpr_int32)((ms - result.tv_sec * 1000) * 1000000); } else { /* Calculation carefully formulated to avoid any possible under/overflow. */ result.tv_sec = (-(999 - (ms + 1000)) / 1000) - 1; - result.tv_nsec = (int)((ms - result.tv_sec * 1000) * 1000000); + result.tv_nsec = (gpr_int32)((ms - result.tv_sec * 1000) * 1000000); } return result; } @@ -197,7 +181,7 @@ gpr_timespec gpr_time_from_hours(long h, gpr_clock_type type) { gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b) { gpr_timespec sum; - int inc = 0; + gpr_int64 inc = 0; GPR_ASSERT(b.clock_type == GPR_TIMESPAN); sum.clock_type = a.clock_type; sum.tv_nsec = a.tv_nsec + b.tv_nsec; @@ -205,17 +189,17 @@ gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b) { sum.tv_nsec -= GPR_NS_PER_SEC; inc++; } - if (a.tv_sec == TYPE_MAX(time_t) || a.tv_sec == TYPE_MIN(time_t)) { + if (a.tv_sec == INT64_MAX || a.tv_sec == INT64_MIN) { sum = a; - } else if (b.tv_sec == TYPE_MAX(time_t) || - (b.tv_sec >= 0 && a.tv_sec >= TYPE_MAX(time_t) - b.tv_sec)) { + } else if (b.tv_sec == INT64_MAX || + (b.tv_sec >= 0 && a.tv_sec >= INT64_MAX - b.tv_sec)) { sum = gpr_inf_future(sum.clock_type); - } else if (b.tv_sec == TYPE_MIN(time_t) || - (b.tv_sec <= 0 && a.tv_sec <= TYPE_MIN(time_t) - b.tv_sec)) { + } else if (b.tv_sec == INT64_MIN || + (b.tv_sec <= 0 && a.tv_sec <= INT64_MIN - b.tv_sec)) { sum = gpr_inf_past(sum.clock_type); } else { sum.tv_sec = a.tv_sec + b.tv_sec; - if (inc != 0 && sum.tv_sec == TYPE_MAX(time_t) - 1) { + if (inc != 0 && sum.tv_sec == INT64_MAX - 1) { sum = gpr_inf_future(sum.clock_type); } else { sum.tv_sec += inc; @@ -226,7 +210,7 @@ gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b) { gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b) { gpr_timespec diff; - int dec = 0; + gpr_int64 dec = 0; if (b.clock_type == GPR_TIMESPAN) { diff.clock_type = a.clock_type; } else { @@ -238,17 +222,17 @@ gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b) { diff.tv_nsec += GPR_NS_PER_SEC; dec++; } - if (a.tv_sec == TYPE_MAX(time_t) || a.tv_sec == TYPE_MIN(time_t)) { + if (a.tv_sec == INT64_MAX || a.tv_sec == INT64_MIN) { diff = a; - } else if (b.tv_sec == TYPE_MIN(time_t) || - (b.tv_sec <= 0 && a.tv_sec >= TYPE_MAX(time_t) + b.tv_sec)) { + } else if (b.tv_sec == INT64_MIN || + (b.tv_sec <= 0 && a.tv_sec >= INT64_MAX + b.tv_sec)) { diff = gpr_inf_future(GPR_CLOCK_REALTIME); - } else if (b.tv_sec == TYPE_MAX(time_t) || - (b.tv_sec >= 0 && a.tv_sec <= TYPE_MIN(time_t) + b.tv_sec)) { + } else if (b.tv_sec == INT64_MAX || + (b.tv_sec >= 0 && a.tv_sec <= INT64_MIN + b.tv_sec)) { diff = gpr_inf_past(GPR_CLOCK_REALTIME); } else { diff.tv_sec = a.tv_sec - b.tv_sec; - if (dec != 0 && diff.tv_sec == TYPE_MIN(time_t) + 1) { + if (dec != 0 && diff.tv_sec == INT64_MIN + 1) { diff = gpr_inf_past(GPR_CLOCK_REALTIME); } else { diff.tv_sec -= dec; @@ -297,11 +281,11 @@ gpr_timespec gpr_convert_clock_type(gpr_timespec t, gpr_clock_type clock_type) { } if (t.tv_nsec == 0) { - if (t.tv_sec == TYPE_MAX(time_t)) { + if (t.tv_sec == INT64_MAX) { t.clock_type = clock_type; return t; } - if (t.tv_sec == TYPE_MIN(time_t)) { + if (t.tv_sec == INT64_MIN) { t.clock_type = clock_type; return t; } diff --git a/src/core/support/time_posix.c b/src/core/support/time_posix.c index 02cfca8555..05d6cc0ca8 100644 --- a/src/core/support/time_posix.c +++ b/src/core/support/time_posix.c @@ -45,7 +45,11 @@ static struct timespec timespec_from_gpr(gpr_timespec gts) { struct timespec rv; - rv.tv_sec = gts.tv_sec; + if (sizeof(time_t) < sizeof(gpr_int64)) { + /* fine to assert, as this is only used in gpr_sleep_until */ + GPR_ASSERT(gts.tv_sec <= INT32_MAX && gts.tv_sec >= INT32_MIN); + } + rv.tv_sec = (time_t)gts.tv_sec; rv.tv_nsec = gts.tv_nsec; return rv; } @@ -53,9 +57,14 @@ static struct timespec timespec_from_gpr(gpr_timespec gts) { #if _POSIX_TIMERS > 0 static gpr_timespec gpr_from_timespec(struct timespec ts, gpr_clock_type clock_type) { + /* + * timespec.tv_sec can have smaller size than gpr_timespec.tv_sec, + * but we are only using this function to implement gpr_now + * so there's no need to handle "infinity" values. + */ gpr_timespec rv; rv.tv_sec = ts.tv_sec; - rv.tv_nsec = (int)ts.tv_nsec; + rv.tv_nsec = (gpr_int32)ts.tv_nsec; rv.clock_type = clock_type; return rv; } @@ -110,8 +119,8 @@ gpr_timespec gpr_now(gpr_clock_type clock) { break; case GPR_CLOCK_MONOTONIC: now_dbl = (mach_absolute_time() - g_time_start) * g_time_scale; - now.tv_sec = (time_t)(now_dbl * 1e-9); - now.tv_nsec = (int)(now_dbl - ((double)now.tv_sec) * 1e9); + now.tv_sec = (gpr_int64)(now_dbl * 1e-9); + now.tv_nsec = (gpr_int32)(now_dbl - ((double)now.tv_sec) * 1e9); break; case GPR_CLOCK_PRECISE: gpr_precise_clock_now(&now); diff --git a/src/core/support/time_precise.c b/src/core/support/time_precise.c index b37517e639..4de1d9b071 100644 --- a/src/core/support/time_precise.c +++ b/src/core/support/time_precise.c @@ -75,8 +75,8 @@ void gpr_precise_clock_now(gpr_timespec *clk) { gpr_get_cycle_counter(&counter); secs = (double)(counter - start_cycle) / cycles_per_second; clk->clock_type = GPR_CLOCK_PRECISE; - clk->tv_sec = (time_t)secs; - clk->tv_nsec = (int)(1e9 * (secs - (double)clk->tv_sec)); + clk->tv_sec = (gpr_int64)secs; + clk->tv_nsec = (gpr_int32)(1e9 * (secs - (double)clk->tv_sec)); } #else /* GRPC_TIMERS_RDTSC */ diff --git a/src/core/support/time_win32.c b/src/core/support/time_win32.c index 623a8d9233..7ccaaa248d 100644 --- a/src/core/support/time_win32.c +++ b/src/core/support/time_win32.c @@ -62,15 +62,15 @@ gpr_timespec gpr_now(gpr_clock_type clock) { switch (clock) { case GPR_CLOCK_REALTIME: _ftime_s(&now_tb); - now_tv.tv_sec = now_tb.time; + now_tv.tv_sec = (gpr_int64)now_tb.time; now_tv.tv_nsec = now_tb.millitm * 1000000; break; case GPR_CLOCK_MONOTONIC: case GPR_CLOCK_PRECISE: QueryPerformanceCounter(×tamp); now_dbl = (timestamp.QuadPart - g_start_time.QuadPart) * g_time_scale; - now_tv.tv_sec = (time_t)now_dbl; - now_tv.tv_nsec = (int)((now_dbl - (double)now_tv.tv_sec) * 1e9); + now_tv.tv_sec = (gpr_int64)now_dbl; + now_tv.tv_nsec = (gpr_int32)((now_dbl - (double)now_tv.tv_sec) * 1e9); break; } return now_tv; diff --git a/src/core/surface/channel.c b/src/core/surface/channel.c index 14fe97c30d..cff8313eef 100644 --- a/src/core/surface/channel.c +++ b/src/core/surface/channel.c @@ -194,10 +194,10 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel, "grpc_channel_create_call(" "channel=%p, parent_call=%p, propagation_mask=%x, cq=%p, method=%s, " "host=%s, " - "deadline=gpr_timespec { tv_sec: %ld, tv_nsec: %d, clock_type: %d }, " + "deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, " "reserved=%p)", 10, (channel, parent_call, (unsigned)propagation_mask, cq, method, host, - (long)deadline.tv_sec, deadline.tv_nsec, (int)deadline.clock_type, + (long long)deadline.tv_sec, (int)deadline.tv_nsec, (int)deadline.clock_type, reserved)); GPR_ASSERT(!reserved); return grpc_channel_create_call_internal( @@ -238,10 +238,10 @@ grpc_call *grpc_channel_create_registered_call( "grpc_channel_create_registered_call(" "channel=%p, parent_call=%p, propagation_mask=%x, completion_queue=%p, " "registered_call_handle=%p, " - "deadline=gpr_timespec { tv_sec: %ld, tv_nsec: %d, clock_type: %d }, " + "deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, " "reserved=%p)", 9, (channel, parent_call, (unsigned)propagation_mask, completion_queue, - registered_call_handle, (long)deadline.tv_sec, deadline.tv_nsec, + registered_call_handle, (long long)deadline.tv_sec, (int)deadline.tv_nsec, (int)deadline.clock_type, reserved)); GPR_ASSERT(!reserved); return grpc_channel_create_call_internal( diff --git a/src/core/surface/channel_connectivity.c b/src/core/surface/channel_connectivity.c index df2774b527..cee1ddb8b9 100644 --- a/src/core/surface/channel_connectivity.c +++ b/src/core/surface/channel_connectivity.c @@ -200,10 +200,10 @@ void grpc_channel_watch_connectivity_state( GRPC_API_TRACE( "grpc_channel_watch_connectivity_state(" "channel=%p, last_observed_state=%d, " - "deadline=gpr_timespec { tv_sec: %ld, tv_nsec: %d, clock_type: %d }, " + "deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, " "cq=%p, tag=%p)", - 7, (channel, (int)last_observed_state, (long)deadline.tv_sec, - deadline.tv_nsec, (int)deadline.clock_type, cq, tag)); + 7, (channel, (int)last_observed_state, (long long)deadline.tv_sec, + (int)deadline.tv_nsec, (int)deadline.clock_type, cq, tag)); grpc_cq_begin_op(cq); diff --git a/src/core/surface/completion_queue.c b/src/core/surface/completion_queue.c index d56e5cbe84..c71b9b02b0 100644 --- a/src/core/surface/completion_queue.c +++ b/src/core/surface/completion_queue.c @@ -247,9 +247,9 @@ grpc_event grpc_completion_queue_next(grpc_completion_queue *cc, GRPC_API_TRACE( "grpc_completion_queue_next(" "cc=%p, " - "deadline=gpr_timespec { tv_sec: %ld, tv_nsec: %d, clock_type: %d }, " + "deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, " "reserved=%p)", - 5, (cc, (long)deadline.tv_sec, deadline.tv_nsec, (int)deadline.clock_type, + 5, (cc, (long long)deadline.tv_sec, (int)deadline.tv_nsec, (int)deadline.clock_type, reserved)); GPR_ASSERT(!reserved); @@ -335,9 +335,9 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, GRPC_API_TRACE( "grpc_completion_queue_pluck(" "cc=%p, tag=%p, " - "deadline=gpr_timespec { tv_sec: %ld, tv_nsec: %d, clock_type: %d }, " + "deadline=gpr_timespec { tv_sec: %lld, tv_nsec: %d, clock_type: %d }, " "reserved=%p)", - 6, (cc, tag, (long)deadline.tv_sec, deadline.tv_nsec, + 6, (cc, tag, (long long)deadline.tv_sec, (int)deadline.tv_nsec, (int)deadline.clock_type, reserved)); GPR_ASSERT(!reserved); diff --git a/src/core/transport/chttp2/timeout_encoding.c b/src/core/transport/chttp2/timeout_encoding.c index cf81c18a20..7ec8b4e8bf 100644 --- a/src/core/transport/chttp2/timeout_encoding.c +++ b/src/core/transport/chttp2/timeout_encoding.c @@ -39,12 +39,12 @@ #include #include "src/core/support/string.h" -static int round_up(int x, int divisor) { +static gpr_int64 round_up(gpr_int64 x, gpr_int64 divisor) { return (x / divisor + (x % divisor != 0)) * divisor; } /* round an integer up to the next value with three significant figures */ -static int round_up_to_three_sig_figs(int x) { +static gpr_int64 round_up_to_three_sig_figs(gpr_int64 x) { if (x < 1000) return x; if (x < 10000) return round_up(x, 10); if (x < 100000) return round_up(x, 100); @@ -74,7 +74,7 @@ static void enc_seconds(char *buffer, gpr_int64 sec) { } } -static void enc_nanos(char *buffer, int x) { +static void enc_nanos(char *buffer, gpr_int64 x) { x = round_up_to_three_sig_figs(x); if (x < 100000) { if (x % 1000 == 0) { @@ -98,7 +98,7 @@ static void enc_nanos(char *buffer, int x) { } } -static void enc_micros(char *buffer, int x) { +static void enc_micros(char *buffer, gpr_int64 x) { x = round_up_to_three_sig_figs(x); if (x < 100000) { if (x % 1000 == 0) { @@ -124,7 +124,7 @@ void grpc_chttp2_encode_timeout(gpr_timespec timeout, char *buffer) { enc_nanos(buffer, timeout.tv_nsec); } else if (timeout.tv_sec < 1000 && timeout.tv_nsec != 0) { enc_micros(buffer, - (int)(timeout.tv_sec * 1000000) + + (gpr_int64)(timeout.tv_sec * 1000000) + (timeout.tv_nsec / 1000 + (timeout.tv_nsec % 1000 != 0))); } else { enc_seconds(buffer, timeout.tv_sec + (timeout.tv_nsec != 0)); diff --git a/src/core/transport/transport_op_string.c b/src/core/transport/transport_op_string.c index f3b6db29d6..98b51afc88 100644 --- a/src/core/transport/transport_op_string.c +++ b/src/core/transport/transport_op_string.c @@ -63,8 +63,8 @@ static void put_metadata_list(gpr_strvec *b, grpc_metadata_batch md) { } if (gpr_time_cmp(md.deadline, gpr_inf_future(md.deadline.clock_type)) != 0) { char *tmp; - gpr_asprintf(&tmp, " deadline=%d.%09d", md.deadline.tv_sec, - md.deadline.tv_nsec); + gpr_asprintf(&tmp, " deadline=%lld.%09d", (long long)md.deadline.tv_sec, + (int)md.deadline.tv_nsec); gpr_strvec_add(b, tmp); } } diff --git a/src/cpp/util/time.cc b/src/cpp/util/time.cc index 6157a37745..9c38b34879 100644 --- a/src/cpp/util/time.cc +++ b/src/cpp/util/time.cc @@ -57,8 +57,8 @@ void Timepoint2Timespec(const system_clock::time_point& from, return; } nanoseconds nsecs = duration_cast(deadline - secs); - to->tv_sec = (time_t)secs.count(); - to->tv_nsec = (int)nsecs.count(); + to->tv_sec = (gpr_int64)secs.count(); + to->tv_nsec = (gpr_int32)nsecs.count(); to->clock_type = GPR_CLOCK_REALTIME; } @@ -73,8 +73,8 @@ void TimepointHR2Timespec(const high_resolution_clock::time_point& from, return; } nanoseconds nsecs = duration_cast(deadline - secs); - to->tv_sec = (time_t)secs.count(); - to->tv_nsec = (int)nsecs.count(); + to->tv_sec = (gpr_int64)secs.count(); + to->tv_nsec = (gpr_int32)nsecs.count(); to->clock_type = GPR_CLOCK_REALTIME; } diff --git a/src/csharp/Grpc.Core.Tests/Internal/TimespecTest.cs b/src/csharp/Grpc.Core.Tests/Internal/TimespecTest.cs index 9be5450d81..48b5d78ca9 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/TimespecTest.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/TimespecTest.cs @@ -82,17 +82,17 @@ namespace Grpc.Core.Internal.Tests public void ToDateTime() { Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), - new Timespec(IntPtr.Zero, 0).ToDateTime()); + new Timespec(0, 0).ToDateTime()); Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 10, DateTimeKind.Utc).AddTicks(50), - new Timespec(new IntPtr(10), 5000).ToDateTime()); + new Timespec(10, 5000).ToDateTime()); Assert.AreEqual(new DateTime(2015, 7, 21, 4, 21, 48, DateTimeKind.Utc), - new Timespec(new IntPtr(1437452508), 0).ToDateTime()); + new Timespec(1437452508, 0).ToDateTime()); // before epoch Assert.AreEqual(new DateTime(1969, 12, 31, 23, 59, 55, DateTimeKind.Utc).AddTicks(10), - new Timespec(new IntPtr(-5), 1000).ToDateTime()); + new Timespec(-5, 1000).ToDateTime()); // infinity Assert.AreEqual(DateTime.MaxValue, Timespec.InfFuture.ToDateTime()); @@ -100,80 +100,62 @@ namespace Grpc.Core.Internal.Tests // nanos are rounded to ticks are rounded up Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddTicks(1), - new Timespec(IntPtr.Zero, 99).ToDateTime()); + new Timespec(0, 99).ToDateTime()); // Illegal inputs Assert.Throws(typeof(InvalidOperationException), - () => new Timespec(new IntPtr(0), -2).ToDateTime()); + () => new Timespec(0, -2).ToDateTime()); Assert.Throws(typeof(InvalidOperationException), - () => new Timespec(new IntPtr(0), 1000 * 1000 * 1000).ToDateTime()); + () => new Timespec(0, 1000 * 1000 * 1000).ToDateTime()); Assert.Throws(typeof(InvalidOperationException), - () => new Timespec(new IntPtr(0), 0, GPRClockType.Monotonic).ToDateTime()); + () => new Timespec(0, 0, GPRClockType.Monotonic).ToDateTime()); } [Test] public void ToDateTime_ReturnsUtc() { - Assert.AreEqual(DateTimeKind.Utc, new Timespec(new IntPtr(1437452508), 0).ToDateTime().Kind); - Assert.AreNotEqual(DateTimeKind.Unspecified, new Timespec(new IntPtr(1437452508), 0).ToDateTime().Kind); + Assert.AreEqual(DateTimeKind.Utc, new Timespec(1437452508, 0).ToDateTime().Kind); + Assert.AreNotEqual(DateTimeKind.Unspecified, new Timespec(1437452508, 0).ToDateTime().Kind); } [Test] public void ToDateTime_Overflow() - { - // we can only get overflow in ticks arithmetic on 64-bit - if (IntPtr.Size == 8) - { - var timespec = new Timespec(new IntPtr(long.MaxValue - 100), 0); - Assert.AreNotEqual(Timespec.InfFuture, timespec); - Assert.AreEqual(DateTime.MaxValue, timespec.ToDateTime()); - - Assert.AreEqual(DateTime.MinValue, new Timespec(new IntPtr(long.MinValue + 100), 0).ToDateTime()); - } - else - { - Console.WriteLine("Test cannot be run on this platform, skipping the test."); - } + { + var timespec = new Timespec(long.MaxValue - 100, 0); + Assert.AreNotEqual(Timespec.InfFuture, timespec); + Assert.AreEqual(DateTime.MaxValue, timespec.ToDateTime()); + + Assert.AreEqual(DateTime.MinValue, new Timespec(long.MinValue + 100, 0).ToDateTime()); } [Test] public void ToDateTime_OutOfDateTimeRange() { - // we can only get out of range on 64-bit, on 32 bit the max - // timestamp is ~ Jan 19 2038, which is far within range of DateTime - // same case for min value. - if (IntPtr.Size == 8) - { - // DateTime range goes up to year 9999, 20000 years from now should - // be out of range. - long seconds = 20000L * 365L * 24L * 3600L; - - var timespec = new Timespec(new IntPtr(seconds), 0); - Assert.AreNotEqual(Timespec.InfFuture, timespec); - Assert.AreEqual(DateTime.MaxValue, timespec.ToDateTime()); - - Assert.AreEqual(DateTime.MinValue, new Timespec(new IntPtr(-seconds), 0).ToDateTime()); - } - else - { - Console.WriteLine("Test cannot be run on this platform, skipping the test"); - } + // DateTime range goes up to year 9999, 20000 years from now should + // be out of range. + long seconds = 20000L * 365L * 24L * 3600L; + + var timespec = new Timespec(seconds, 0); + Assert.AreNotEqual(Timespec.InfFuture, timespec); + Assert.AreEqual(DateTime.MaxValue, timespec.ToDateTime()); + + Assert.AreEqual(DateTime.MinValue, new Timespec(-seconds, 0).ToDateTime()); } [Test] public void FromDateTime() { - Assert.AreEqual(new Timespec(IntPtr.Zero, 0), + Assert.AreEqual(new Timespec(0, 0), Timespec.FromDateTime(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc))); - Assert.AreEqual(new Timespec(new IntPtr(10), 5000), + Assert.AreEqual(new Timespec(10, 5000), Timespec.FromDateTime(new DateTime(1970, 1, 1, 0, 0, 10, DateTimeKind.Utc).AddTicks(50))); - Assert.AreEqual(new Timespec(new IntPtr(1437452508), 0), + Assert.AreEqual(new Timespec(1437452508, 0), Timespec.FromDateTime(new DateTime(2015, 7, 21, 4, 21, 48, DateTimeKind.Utc))); // before epoch - Assert.AreEqual(new Timespec(new IntPtr(-5), 1000), + Assert.AreEqual(new Timespec(-5, 1000), Timespec.FromDateTime(new DateTime(1969, 12, 31, 23, 59, 55, DateTimeKind.Utc).AddTicks(10))); // infinity @@ -184,21 +166,6 @@ namespace Grpc.Core.Internal.Tests Assert.Throws(typeof(ArgumentException), () => Timespec.FromDateTime(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Unspecified))); } - - [Test] - public void FromDateTime_OutOfTimespecRange() - { - // we can only get overflow in Timespec on 32-bit - if (IntPtr.Size == 4) - { - Assert.AreEqual(Timespec.InfFuture, Timespec.FromDateTime(new DateTime(2040, 1, 1, 0, 0, 0, DateTimeKind.Utc))); - Assert.AreEqual(Timespec.InfPast, Timespec.FromDateTime(new DateTime(1800, 1, 1, 0, 0, 0, DateTimeKind.Utc))); - } - else - { - Console.WriteLine("Test cannot be run on this platform, skipping the test."); - } - } // Test attribute commented out to prevent running as part of the default test suite. // [Test] diff --git a/src/csharp/Grpc.Core/Internal/Timespec.cs b/src/csharp/Grpc.Core/Internal/Timespec.cs index 38fc067d9f..3031175c8a 100644 --- a/src/csharp/Grpc.Core/Internal/Timespec.cs +++ b/src/csharp/Grpc.Core/Internal/Timespec.cs @@ -63,20 +63,18 @@ namespace Grpc.Core.Internal [DllImport("grpc_csharp_ext.dll")] static extern int gprsharp_sizeof_timespec(); - public Timespec(IntPtr tv_sec, int tv_nsec) : this(tv_sec, tv_nsec, GPRClockType.Realtime) + public Timespec(long tv_sec, int tv_nsec) : this(tv_sec, tv_nsec, GPRClockType.Realtime) { } - public Timespec(IntPtr tv_sec, int tv_nsec, GPRClockType clock_type) + public Timespec(long tv_sec, int tv_nsec, GPRClockType clock_type) { this.tv_sec = tv_sec; this.tv_nsec = tv_nsec; this.clock_type = clock_type; } - // NOTE: on linux 64bit sizeof(gpr_timespec) = 16, on windows 32bit sizeof(gpr_timespec) = 8 - // so IntPtr seems to have the right size to work on both. - private System.IntPtr tv_sec; + private long tv_sec; private int tv_nsec; private GPRClockType clock_type; @@ -116,7 +114,7 @@ namespace Grpc.Core.Internal /// /// Seconds since unix epoch. /// - public IntPtr TimevalSeconds + public long TimevalSeconds { get { @@ -176,18 +174,18 @@ namespace Grpc.Core.Internal { // convert nanos to ticks, round up to the nearest tick long ticksFromNanos = tv_nsec / NanosPerTick + ((tv_nsec % NanosPerTick != 0) ? 1 : 0); - long ticksTotal = checked(tv_sec.ToInt64() * TicksPerSecond + ticksFromNanos); + long ticksTotal = checked(tv_sec * TicksPerSecond + ticksFromNanos); return UnixEpoch.AddTicks(ticksTotal); } catch (OverflowException) { // ticks out of long range - return tv_sec.ToInt64() > 0 ? DateTime.MaxValue : DateTime.MinValue; + return tv_sec > 0 ? DateTime.MaxValue : DateTime.MinValue; } catch (ArgumentOutOfRangeException) { // resulting date time would be larger than MaxValue - return tv_sec.ToInt64() > 0 ? DateTime.MaxValue : DateTime.MinValue; + return tv_sec > 0 ? DateTime.MaxValue : DateTime.MinValue; } } @@ -226,12 +224,7 @@ namespace Grpc.Core.Internal seconds--; nanos += (int)NanosPerSecond; } - // new IntPtr possibly throws OverflowException - return new Timespec(new IntPtr(seconds), nanos); - } - catch (OverflowException) - { - return dateTime > UnixEpoch ? Timespec.InfFuture : Timespec.InfPast; + return new Timespec(seconds, nanos); } catch (ArgumentOutOfRangeException) { diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd index 10c948cd0a..643cdc9e3d 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd @@ -60,6 +60,8 @@ cdef extern from "grpc/support/port_platform.h": # type exactly; just close enough that the operations will be supported in the # underlying C layers. ctypedef unsigned int gpr_uint32 + ctypedef int gpr_int32 + ctypedef long int gpr_int64 cdef extern from "grpc/support/time.h": @@ -71,8 +73,8 @@ cdef extern from "grpc/support/time.h": GPR_TIMESPAN ctypedef struct gpr_timespec: - libc.time.time_t seconds "tv_sec" - int nanoseconds "tv_nsec" + gpr_int64 seconds "tv_sec" + gpr_int32 nanoseconds "tv_nsec" gpr_clock_type clock_type gpr_timespec gpr_time_0(gpr_clock_type type) diff --git a/src/ruby/ext/grpc/rb_grpc.c b/src/ruby/ext/grpc/rb_grpc.c index 7c7c2d3440..8318e12795 100644 --- a/src/ruby/ext/grpc/rb_grpc.c +++ b/src/ruby/ext/grpc/rb_grpc.c @@ -91,7 +91,7 @@ static ID id_tv_sec; static ID id_tv_nsec; /** - * grpc_rb_time_timeval creates a time_eval from a ruby time object. + * grpc_rb_time_timeval creates a timeval from a ruby time object. * * This func is copied from ruby source, MRI/source/time.c, which is published * under the same license as the ruby.h, on which the entire extensions is @@ -137,7 +137,7 @@ gpr_timespec grpc_rb_time_timeval(VALUE time, int interval) { d += 1; f -= 1; } - t.tv_sec = (time_t)f; + t.tv_sec = (gpr_int64)f; if (f != t.tv_sec) { rb_raise(rb_eRangeError, "%f out of Time range", RFLOAT_VALUE(time)); -- cgit v1.2.3