From 61f93b2b0643edb1b460aba080e4ea1d2b5cfea3 Mon Sep 17 00:00:00 2001
From: Jan Tattermusch <jtattermusch@google.com>
Date: Thu, 12 Feb 2015 12:45:52 -0800
Subject: [PATCH] Fixed Timespec to work on Windows, fixes in ServerSafeHandle

---
 .../GrpcCore/Internal/ServerSafeHandle.cs     | 34 +++++++++----------
 src/csharp/GrpcCore/Internal/Timespec.cs      | 15 ++++----
 src/csharp/GrpcCoreTests/TimespecTest.cs      | 18 +++++-----
 3 files changed, 34 insertions(+), 33 deletions(-)

diff --git a/src/csharp/GrpcCore/Internal/ServerSafeHandle.cs b/src/csharp/GrpcCore/Internal/ServerSafeHandle.cs
index 82587c88b7..391a1acd01 100644
--- a/src/csharp/GrpcCore/Internal/ServerSafeHandle.cs
+++ b/src/csharp/GrpcCore/Internal/ServerSafeHandle.cs
@@ -10,31 +10,31 @@ namespace Google.GRPC.Core.Internal
     /// </summary>
     internal sealed class ServerSafeHandle : SafeHandleZeroIsInvalid
     {
-        [DllImport("grpc_csharp_ext.dll", EntryPoint = "grpc_server_request_call_old")]
-        static extern GRPCCallError grpc_server_request_call_old_CALLBACK(ServerSafeHandle server, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback);
+        [DllImport("grpc_csharp_ext.dll", EntryPoint = "grpcsharp_server_request_call_old")]
+        static extern GRPCCallError grpcsharp_server_request_call_old_CALLBACK(ServerSafeHandle server, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback);
 
         [DllImport("grpc_csharp_ext.dll")]
-        static extern ServerSafeHandle grpc_server_create(CompletionQueueSafeHandle cq, IntPtr args);
+        static extern ServerSafeHandle grpcsharp_server_create(CompletionQueueSafeHandle cq, IntPtr args);
 
         // TODO: check int representation size
         [DllImport("grpc_csharp_ext.dll")]
-        static extern int grpc_server_add_http2_port(ServerSafeHandle server, string addr);
+        static extern int grpcsharp_server_add_http2_port(ServerSafeHandle server, string addr);
 
         // TODO: check int representation size
         [DllImport("grpc_csharp_ext.dll")]
-        static extern int grpc_server_add_secure_http2_port(ServerSafeHandle server, string addr);
+        static extern int grpcsharp_server_add_secure_http2_port(ServerSafeHandle server, string addr);
 
         [DllImport("grpc_csharp_ext.dll")]
-        static extern void grpc_server_start(ServerSafeHandle server);
+        static extern void grpcsharp_server_start(ServerSafeHandle server);
 
         [DllImport("grpc_csharp_ext.dll")]
-        static extern void grpc_server_shutdown(ServerSafeHandle server);
+        static extern void grpcsharp_server_shutdown(ServerSafeHandle server);
 
-        [DllImport("grpc_csharp_ext.dll", EntryPoint = "grpc_server_shutdown_and_notify")]
-        static extern void grpc_server_shutdown_and_notify_CALLBACK(ServerSafeHandle server, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback);
+        [DllImport("grpc_csharp_ext.dll", EntryPoint = "grpcsharp_server_shutdown_and_notify")]
+        static extern void grpcsharp_server_shutdown_and_notify_CALLBACK(ServerSafeHandle server, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback);
 
         [DllImport("grpc_csharp_ext.dll")]
-        static extern void grpc_server_destroy(IntPtr server);
+        static extern void grpcsharp_server_destroy(IntPtr server);
 
         private ServerSafeHandle()
         {
@@ -43,38 +43,38 @@ namespace Google.GRPC.Core.Internal
         public static ServerSafeHandle NewServer(CompletionQueueSafeHandle cq, IntPtr args)
         {
             // TODO: also grpc_secure_server_create...
-            return grpc_server_create(cq, args);
+            return grpcsharp_server_create(cq, args);
         }
 
         public int AddPort(string addr)
         {
             // TODO: also grpc_server_add_secure_http2_port...
-            return grpc_server_add_http2_port(this, addr);
+            return grpcsharp_server_add_http2_port(this, addr);
         }
 
         public void Start()
         {
-            grpc_server_start(this);
+            grpcsharp_server_start(this);
         }
 
         public void Shutdown()
         {
-            grpc_server_shutdown(this);
+            grpcsharp_server_shutdown(this);
         }
 
         public void ShutdownAndNotify(EventCallbackDelegate callback)
         {
-            grpc_server_shutdown_and_notify_CALLBACK(this, callback);
+            grpcsharp_server_shutdown_and_notify_CALLBACK(this, callback);
         }
 
         public GRPCCallError RequestCall(EventCallbackDelegate callback)
         {
-            return grpc_server_request_call_old_CALLBACK(this, callback);
+            return grpcsharp_server_request_call_old_CALLBACK(this, callback);
         }
 
         protected override bool ReleaseHandle()
         {
-            grpc_server_destroy(handle);
+            grpcsharp_server_destroy(handle);
             return true;
         }
     }
diff --git a/src/csharp/GrpcCore/Internal/Timespec.cs b/src/csharp/GrpcCore/Internal/Timespec.cs
index c069829d8c..c45926707f 100644
--- a/src/csharp/GrpcCore/Internal/Timespec.cs
+++ b/src/csharp/GrpcCore/Internal/Timespec.cs
@@ -22,10 +22,11 @@ namespace Google.GRPC.Core.Internal
         [DllImport("grpc_csharp_ext.dll")]
         static extern int gprsharp_sizeof_timespec();
 
-		// 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;
+        // TODO: revisit this.
+		// 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.
+		public System.IntPtr tv_sec;
+		public System.IntPtr tv_nsec;
 
 		/// <summary>
 		/// Timespec a long time in the future.
@@ -67,12 +68,12 @@ namespace Google.GRPC.Core.Internal
         }
 
         public Timespec Add(TimeSpan timeSpan) {
-            long nanos = tv_nsec + (timeSpan.Ticks % TimeSpan.TicksPerSecond) * nanosPerTick;
+            long nanos = tv_nsec.ToInt64() + (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; 
+            result.tv_nsec = new IntPtr(nanos % nanosPerSecond);
+            result.tv_sec = new IntPtr(tv_sec.ToInt64() + (timeSpan.Ticks / TimeSpan.TicksPerSecond) + overflow_sec); 
             return result;
         }
 	}
diff --git a/src/csharp/GrpcCoreTests/TimespecTest.cs b/src/csharp/GrpcCoreTests/TimespecTest.cs
index 4de310372d..cab59fa5b3 100644
--- a/src/csharp/GrpcCoreTests/TimespecTest.cs
+++ b/src/csharp/GrpcCoreTests/TimespecTest.cs
@@ -28,28 +28,28 @@ namespace Google.GRPC.Core.Internal.Tests
         [Test]
         public void Add()
         {
-            var t = new Timespec { tv_sec = 12345, tv_nsec = 123456789 };
+            var t = new Timespec { tv_sec = new IntPtr(12345), tv_nsec = new IntPtr(123456789) };
             var result = t.Add(TimeSpan.FromTicks(TimeSpan.TicksPerSecond * 10));
-            Assert.AreEqual(result.tv_sec, 12355);
-            Assert.AreEqual(result.tv_nsec, 123456789);
+            Assert.AreEqual(result.tv_sec, new IntPtr(12355));
+            Assert.AreEqual(result.tv_nsec, new IntPtr(123456789));
         }
 
         [Test]
         public void Add_Nanos()
         {
-            var t = new Timespec { tv_sec = 12345, tv_nsec = 123456789 };
+            var t = new Timespec { tv_sec = new IntPtr(12345), tv_nsec = new IntPtr(123456789) };
             var result = t.Add(TimeSpan.FromTicks(10));
-            Assert.AreEqual(result.tv_sec, 12345);
-            Assert.AreEqual(result.tv_nsec, 123456789 + 1000);
+            Assert.AreEqual(result.tv_sec, new IntPtr(12345));
+            Assert.AreEqual(result.tv_nsec, new IntPtr(123456789 + 1000));
         }
 
         [Test]
         public void Add_NanosOverflow()
         {
-            var t = new Timespec { tv_sec = 12345, tv_nsec = 999999999 };
+            var t = new Timespec { tv_sec = new IntPtr(12345), tv_nsec = new IntPtr(999999999) };
             var result = t.Add(TimeSpan.FromTicks(TimeSpan.TicksPerSecond * 10 + 10));
-            Assert.AreEqual(result.tv_sec, 12356);
-            Assert.AreEqual(result.tv_nsec, 999);
+            Assert.AreEqual(result.tv_sec, new IntPtr(12356));
+            Assert.AreEqual(result.tv_nsec, new IntPtr(999));
         }
     }
 }
-- 
GitLab