aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/csharp/GrpcCore/Internal/Timespec.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/csharp/GrpcCore/Internal/Timespec.cs')
-rw-r--r--src/csharp/GrpcCore/Internal/Timespec.cs67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/csharp/GrpcCore/Internal/Timespec.cs b/src/csharp/GrpcCore/Internal/Timespec.cs
new file mode 100644
index 0000000000..8ffaf70bbf
--- /dev/null
+++ b/src/csharp/GrpcCore/Internal/Timespec.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+namespace Google.GRPC.Core.Internal
+{
+ /// <summary>
+ /// gpr_timespec from grpc/support/time.h
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct Timespec
+ {
+ const int nanosPerSecond = 1000 * 1000 * 1000;
+ const int nanosPerTick = 100;
+
+ [DllImport("libgpr.so")]
+ static extern Timespec gpr_now();
+
+ // TODO: this only works on 64bit linux, can we autoselect the right size of ints?
+ // perhaps using IntPtr would work.
+ public System.Int64 tv_sec;
+ public System.Int64 tv_nsec;
+
+ /// <summary>
+ /// Timespec a long time in the future.
+ /// </summary>
+ public static Timespec InfFuture
+ {
+ get
+ {
+ // TODO: set correct value based on the length of the struct
+ return new Timespec { tv_sec = Int32.MaxValue, tv_nsec = 0 };
+ }
+ }
+
+ public static Timespec Now
+ {
+ get
+ {
+ return gpr_now();
+ }
+ }
+
+ /// <summary>
+ /// Creates a GPR deadline from current instant and given timeout.
+ /// </summary>
+ /// <returns>The from timeout.</returns>
+ public static Timespec DeadlineFromTimeout(TimeSpan timeout) {
+ if (timeout == Timeout.InfiniteTimeSpan)
+ {
+ return Timespec.InfFuture;
+ }
+ return Timespec.Now.Add(timeout);
+ }
+
+ public Timespec Add(TimeSpan timeSpan) {
+ long nanos = tv_nsec + (timeSpan.Ticks % TimeSpan.TicksPerSecond) * nanosPerTick;
+ long overflow_sec = (nanos > nanosPerSecond) ? 1 : 0;
+
+ Timespec result;
+ result.tv_nsec = nanos % nanosPerSecond;
+ result.tv_sec = tv_sec + (timeSpan.Ticks / TimeSpan.TicksPerSecond) + overflow_sec;
+ return result;
+ }
+ }
+}
+