Fixed Timespec to work on Windows, fixes in ServerSafeHandle

pull/505/head
Jan Tattermusch 10 years ago
parent c9562b6c4b
commit 61f93b2b06
  1. 34
      src/csharp/GrpcCore/Internal/ServerSafeHandle.cs
  2. 15
      src/csharp/GrpcCore/Internal/Timespec.cs
  3. 18
      src/csharp/GrpcCoreTests/TimespecTest.cs

@ -10,31 +10,31 @@ namespace Google.GRPC.Core.Internal
/// </summary> /// </summary>
internal sealed class ServerSafeHandle : SafeHandleZeroIsInvalid internal sealed class ServerSafeHandle : SafeHandleZeroIsInvalid
{ {
[DllImport("grpc_csharp_ext.dll", EntryPoint = "grpc_server_request_call_old")] [DllImport("grpc_csharp_ext.dll", EntryPoint = "grpcsharp_server_request_call_old")]
static extern GRPCCallError grpc_server_request_call_old_CALLBACK(ServerSafeHandle server, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback); static extern GRPCCallError grpcsharp_server_request_call_old_CALLBACK(ServerSafeHandle server, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback);
[DllImport("grpc_csharp_ext.dll")] [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 // TODO: check int representation size
[DllImport("grpc_csharp_ext.dll")] [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 // TODO: check int representation size
[DllImport("grpc_csharp_ext.dll")] [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")] [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")] [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")] [DllImport("grpc_csharp_ext.dll", EntryPoint = "grpcsharp_server_shutdown_and_notify")]
static extern void grpc_server_shutdown_and_notify_CALLBACK(ServerSafeHandle server, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback); static extern void grpcsharp_server_shutdown_and_notify_CALLBACK(ServerSafeHandle server, [MarshalAs(UnmanagedType.FunctionPtr)] EventCallbackDelegate callback);
[DllImport("grpc_csharp_ext.dll")] [DllImport("grpc_csharp_ext.dll")]
static extern void grpc_server_destroy(IntPtr server); static extern void grpcsharp_server_destroy(IntPtr server);
private ServerSafeHandle() private ServerSafeHandle()
{ {
@ -43,38 +43,38 @@ namespace Google.GRPC.Core.Internal
public static ServerSafeHandle NewServer(CompletionQueueSafeHandle cq, IntPtr args) public static ServerSafeHandle NewServer(CompletionQueueSafeHandle cq, IntPtr args)
{ {
// TODO: also grpc_secure_server_create... // TODO: also grpc_secure_server_create...
return grpc_server_create(cq, args); return grpcsharp_server_create(cq, args);
} }
public int AddPort(string addr) public int AddPort(string addr)
{ {
// TODO: also grpc_server_add_secure_http2_port... // 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() public void Start()
{ {
grpc_server_start(this); grpcsharp_server_start(this);
} }
public void Shutdown() public void Shutdown()
{ {
grpc_server_shutdown(this); grpcsharp_server_shutdown(this);
} }
public void ShutdownAndNotify(EventCallbackDelegate callback) 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) 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() protected override bool ReleaseHandle()
{ {
grpc_server_destroy(handle); grpcsharp_server_destroy(handle);
return true; return true;
} }
} }

@ -22,10 +22,11 @@ namespace Google.GRPC.Core.Internal
[DllImport("grpc_csharp_ext.dll")] [DllImport("grpc_csharp_ext.dll")]
static extern int gprsharp_sizeof_timespec(); static extern int gprsharp_sizeof_timespec();
// TODO: this only works on 64bit linux, can we autoselect the right size of ints? // TODO: revisit this.
// perhaps using IntPtr would work. // NOTE: on linux 64bit sizeof(gpr_timespec) = 16, on windows 32bit sizeof(gpr_timespec) = 8
public System.Int64 tv_sec; // so IntPtr seems to have the right size to work on both.
public System.Int64 tv_nsec; public System.IntPtr tv_sec;
public System.IntPtr tv_nsec;
/// <summary> /// <summary>
/// Timespec a long time in the future. /// Timespec a long time in the future.
@ -67,12 +68,12 @@ namespace Google.GRPC.Core.Internal
} }
public Timespec Add(TimeSpan timeSpan) { 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; long overflow_sec = (nanos > nanosPerSecond) ? 1 : 0;
Timespec result; Timespec result;
result.tv_nsec = nanos % nanosPerSecond; result.tv_nsec = new IntPtr(nanos % nanosPerSecond);
result.tv_sec = tv_sec + (timeSpan.Ticks / TimeSpan.TicksPerSecond) + overflow_sec; result.tv_sec = new IntPtr(tv_sec.ToInt64() + (timeSpan.Ticks / TimeSpan.TicksPerSecond) + overflow_sec);
return result; return result;
} }
} }

@ -28,28 +28,28 @@ namespace Google.GRPC.Core.Internal.Tests
[Test] [Test]
public void Add() 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)); var result = t.Add(TimeSpan.FromTicks(TimeSpan.TicksPerSecond * 10));
Assert.AreEqual(result.tv_sec, 12355); Assert.AreEqual(result.tv_sec, new IntPtr(12355));
Assert.AreEqual(result.tv_nsec, 123456789); Assert.AreEqual(result.tv_nsec, new IntPtr(123456789));
} }
[Test] [Test]
public void Add_Nanos() 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)); var result = t.Add(TimeSpan.FromTicks(10));
Assert.AreEqual(result.tv_sec, 12345); Assert.AreEqual(result.tv_sec, new IntPtr(12345));
Assert.AreEqual(result.tv_nsec, 123456789 + 1000); Assert.AreEqual(result.tv_nsec, new IntPtr(123456789 + 1000));
} }
[Test] [Test]
public void Add_NanosOverflow() 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)); var result = t.Add(TimeSpan.FromTicks(TimeSpan.TicksPerSecond * 10 + 10));
Assert.AreEqual(result.tv_sec, 12356); Assert.AreEqual(result.tv_sec, new IntPtr(12356));
Assert.AreEqual(result.tv_nsec, 999); Assert.AreEqual(result.tv_nsec, new IntPtr(999));
} }
} }
} }

Loading…
Cancel
Save