aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/csharp/Grpc.Core/Internal
diff options
context:
space:
mode:
Diffstat (limited to 'src/csharp/Grpc.Core/Internal')
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCall.cs32
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCallBase.cs66
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCallServer.cs36
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCompletion.cs2
-rw-r--r--src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs2
-rw-r--r--src/csharp/Grpc.Core/Internal/CStringSafeHandle.cs2
-rw-r--r--src/csharp/Grpc.Core/Internal/CallCredentialsSafeHandle.cs2
-rw-r--r--src/csharp/Grpc.Core/Internal/CallSafeHandle.cs2
-rw-r--r--src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs2
-rw-r--r--src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs2
-rw-r--r--src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs2
-rw-r--r--src/csharp/Grpc.Core/Internal/CompletionQueueEvent.cs2
-rw-r--r--src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs4
-rw-r--r--src/csharp/Grpc.Core/Internal/CompletionRegistry.cs4
-rw-r--r--src/csharp/Grpc.Core/Internal/DefaultSslRootsOverride.cs4
-rw-r--r--src/csharp/Grpc.Core/Internal/Enums.cs2
-rw-r--r--src/csharp/Grpc.Core/Internal/InterceptingCallInvoker.cs134
-rw-r--r--src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs2
-rw-r--r--src/csharp/Grpc.Core/Internal/NativeExtension.cs25
-rw-r--r--src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs2
-rw-r--r--src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs4
-rw-r--r--src/csharp/Grpc.Core/Internal/NativeMethods.cs2
-rw-r--r--src/csharp/Grpc.Core/Internal/PlatformApis.cs8
-rw-r--r--src/csharp/Grpc.Core/Internal/ServerCallHandler.cs8
-rw-r--r--src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs4
-rw-r--r--src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs2
-rw-r--r--src/csharp/Grpc.Core/Internal/Timespec.cs8
-rw-r--r--src/csharp/Grpc.Core/Internal/UnimplementedCallInvoker.cs75
-rw-r--r--src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs4
29 files changed, 350 insertions, 94 deletions
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
index 7dc4490281..016e1b8587 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
@@ -1,6 +1,6 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -99,7 +99,7 @@ namespace Grpc.Core.Internal
lock (myLock)
{
- Preconditions.CheckState(!started);
+ GrpcPreconditions.CheckState(!started);
started = true;
Initialize(cq);
@@ -141,7 +141,7 @@ namespace Grpc.Core.Internal
{
lock (myLock)
{
- Preconditions.CheckState(!started);
+ GrpcPreconditions.CheckState(!started);
started = true;
Initialize(environment.CompletionQueue);
@@ -168,7 +168,7 @@ namespace Grpc.Core.Internal
{
lock (myLock)
{
- Preconditions.CheckState(!started);
+ GrpcPreconditions.CheckState(!started);
started = true;
Initialize(environment.CompletionQueue);
@@ -192,7 +192,7 @@ namespace Grpc.Core.Internal
{
lock (myLock)
{
- Preconditions.CheckState(!started);
+ GrpcPreconditions.CheckState(!started);
started = true;
Initialize(environment.CompletionQueue);
@@ -217,7 +217,7 @@ namespace Grpc.Core.Internal
{
lock (myLock)
{
- Preconditions.CheckState(!started);
+ GrpcPreconditions.CheckState(!started);
started = true;
Initialize(environment.CompletionQueue);
@@ -257,10 +257,20 @@ namespace Grpc.Core.Internal
{
lock (myLock)
{
- Preconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
- CheckSendingAllowed();
+ GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
+ CheckSendingAllowed(allowFinished: true);
- call.StartSendCloseFromClient(HandleHalfclosed);
+ if (!disposed && !finished)
+ {
+ call.StartSendCloseFromClient(HandleSendCloseFromClientFinished);
+ }
+ else
+ {
+ // In case the call has already been finished by the serverside,
+ // the halfclose has already been done implicitly, so we only
+ // emit the notification for the completion delegate.
+ Task.Run(() => HandleSendCloseFromClientFinished(true));
+ }
halfcloseRequested = true;
sendCompletionDelegate = completionDelegate;
@@ -297,7 +307,7 @@ namespace Grpc.Core.Internal
{
lock (myLock)
{
- Preconditions.CheckState(finishedStatus.HasValue, "Status can only be accessed once the call has finished.");
+ GrpcPreconditions.CheckState(finishedStatus.HasValue, "Status can only be accessed once the call has finished.");
return finishedStatus.Value.Status;
}
}
@@ -310,7 +320,7 @@ namespace Grpc.Core.Internal
{
lock (myLock)
{
- Preconditions.CheckState(finishedStatus.HasValue, "Trailers can only be accessed once the call has finished.");
+ GrpcPreconditions.CheckState(finishedStatus.HasValue, "Trailers can only be accessed once the call has finished.");
return finishedStatus.Value.Trailers;
}
}
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
index 81a9a40fcc..ccd047f469 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
@@ -1,6 +1,6 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -79,9 +79,9 @@ namespace Grpc.Core.Internal
public AsyncCallBase(Func<TWrite, byte[]> serializer, Func<byte[], TRead> deserializer, GrpcEnvironment environment)
{
- this.serializer = Preconditions.CheckNotNull(serializer);
- this.deserializer = Preconditions.CheckNotNull(deserializer);
- this.environment = Preconditions.CheckNotNull(environment);
+ this.serializer = GrpcPreconditions.CheckNotNull(serializer);
+ this.deserializer = GrpcPreconditions.CheckNotNull(deserializer);
+ this.environment = GrpcPreconditions.CheckNotNull(environment);
}
/// <summary>
@@ -91,7 +91,7 @@ namespace Grpc.Core.Internal
{
lock (myLock)
{
- Preconditions.CheckState(started);
+ GrpcPreconditions.CheckState(started);
cancelRequested = true;
if (!disposed)
@@ -135,8 +135,8 @@ namespace Grpc.Core.Internal
lock (myLock)
{
- Preconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
- CheckSendingAllowed();
+ GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
+ CheckSendingAllowed(allowFinished: false);
call.StartSendMessage(HandleSendFinished, payload, writeFlags, !initialMetadataSent);
@@ -154,7 +154,7 @@ namespace Grpc.Core.Internal
{
lock (myLock)
{
- Preconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
+ GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
CheckReadingAllowed();
call.StartReceiveMessage(HandleReadFinished);
@@ -202,24 +202,24 @@ namespace Grpc.Core.Internal
{
}
- protected void CheckSendingAllowed()
+ protected void CheckSendingAllowed(bool allowFinished)
{
- Preconditions.CheckState(started);
+ GrpcPreconditions.CheckState(started);
CheckNotCancelled();
- Preconditions.CheckState(!disposed);
+ GrpcPreconditions.CheckState(!disposed || allowFinished);
- Preconditions.CheckState(!halfcloseRequested, "Already halfclosed.");
- Preconditions.CheckState(!finished, "Already finished.");
- Preconditions.CheckState(sendCompletionDelegate == null, "Only one write can be pending at a time");
+ GrpcPreconditions.CheckState(!halfcloseRequested, "Already halfclosed.");
+ GrpcPreconditions.CheckState(!finished || allowFinished, "Already finished.");
+ GrpcPreconditions.CheckState(sendCompletionDelegate == null, "Only one write can be pending at a time");
}
protected virtual void CheckReadingAllowed()
{
- Preconditions.CheckState(started);
- Preconditions.CheckState(!disposed);
+ GrpcPreconditions.CheckState(started);
+ GrpcPreconditions.CheckState(!disposed);
- Preconditions.CheckState(!readingDone, "Stream has already been closed.");
- Preconditions.CheckState(readCompletionDelegate == null, "Only one read can be pending at a time");
+ GrpcPreconditions.CheckState(!readingDone, "Stream has already been closed.");
+ GrpcPreconditions.CheckState(readCompletionDelegate == null, "Only one read can be pending at a time");
}
protected void CheckNotCancelled()
@@ -294,9 +294,9 @@ namespace Grpc.Core.Internal
}
/// <summary>
- /// Handles halfclose completion.
+ /// Handles halfclose (send close from client) completion.
/// </summary>
- protected void HandleHalfclosed(bool success)
+ protected void HandleSendCloseFromClientFinished(bool success)
{
AsyncCompletionDelegate<object> origCompletionDelegate = null;
lock (myLock)
@@ -309,7 +309,31 @@ namespace Grpc.Core.Internal
if (!success)
{
- FireCompletion(origCompletionDelegate, null, new InvalidOperationException("Halfclose failed"));
+ FireCompletion(origCompletionDelegate, null, new InvalidOperationException("Sending close from client has failed."));
+ }
+ else
+ {
+ FireCompletion(origCompletionDelegate, null, null);
+ }
+ }
+
+ /// <summary>
+ /// Handles send status from server completion.
+ /// </summary>
+ protected void HandleSendStatusFromServerFinished(bool success)
+ {
+ AsyncCompletionDelegate<object> origCompletionDelegate = null;
+ lock (myLock)
+ {
+ origCompletionDelegate = sendCompletionDelegate;
+ sendCompletionDelegate = null;
+
+ ReleaseResourcesIfPossible();
+ }
+
+ if (!success)
+ {
+ FireCompletion(origCompletionDelegate, null, new InvalidOperationException("Error sending status from server."));
}
else
{
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
index 6752d3fab3..bea2b3660c 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
@@ -1,6 +1,6 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -53,7 +53,7 @@ namespace Grpc.Core.Internal
public AsyncCallServer(Func<TResponse, byte[]> serializer, Func<byte[], TRequest> deserializer, GrpcEnvironment environment, Server server) : base(serializer, deserializer, environment)
{
- this.server = Preconditions.CheckNotNull(server);
+ this.server = GrpcPreconditions.CheckNotNull(server);
}
public void Initialize(CallSafeHandle call)
@@ -71,7 +71,7 @@ namespace Grpc.Core.Internal
{
lock (myLock)
{
- Preconditions.CheckNotNull(call);
+ GrpcPreconditions.CheckNotNull(call);
started = true;
@@ -108,14 +108,14 @@ namespace Grpc.Core.Internal
{
lock (myLock)
{
- Preconditions.CheckNotNull(headers, "metadata");
- Preconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
+ GrpcPreconditions.CheckNotNull(headers, "metadata");
+ GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
- Preconditions.CheckState(!initialMetadataSent, "Response headers can only be sent once per call.");
- Preconditions.CheckState(streamingWritesCounter == 0, "Response headers can only be sent before the first write starts.");
- CheckSendingAllowed();
+ GrpcPreconditions.CheckState(!initialMetadataSent, "Response headers can only be sent once per call.");
+ GrpcPreconditions.CheckState(streamingWritesCounter == 0, "Response headers can only be sent before the first write starts.");
+ CheckSendingAllowed(allowFinished: false);
- Preconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
+ GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
using (var metadataArray = MetadataArraySafeHandle.Create(headers))
{
@@ -136,12 +136,12 @@ namespace Grpc.Core.Internal
{
lock (myLock)
{
- Preconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
- CheckSendingAllowed();
+ GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
+ CheckSendingAllowed(allowFinished: false);
using (var metadataArray = MetadataArraySafeHandle.Create(trailers))
{
- call.StartSendStatusFromServer(HandleHalfclosed, status, metadataArray, !initialMetadataSent);
+ call.StartSendStatusFromServer(HandleSendStatusFromServerFinished, status, metadataArray, !initialMetadataSent);
}
halfcloseRequested = true;
readingDone = true;
@@ -177,7 +177,7 @@ namespace Grpc.Core.Internal
protected override void CheckReadingAllowed()
{
base.CheckReadingAllowed();
- Preconditions.CheckArgument(!cancelRequested);
+ GrpcPreconditions.CheckArgument(!cancelRequested);
}
protected override void OnAfterReleaseResources()
@@ -193,16 +193,6 @@ namespace Grpc.Core.Internal
lock (myLock)
{
finished = true;
-
- if (cancelled)
- {
- // Once we cancel, we don't have to care that much
- // about reads and writes.
-
- // TODO(jtattermusch): is this still necessary?
- Cancel();
- }
-
ReleaseResourcesIfPossible();
}
// TODO(jtattermusch): handle error
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCompletion.cs b/src/csharp/Grpc.Core/Internal/AsyncCompletion.cs
index d5bbf676ff..7e86fddb4d 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCompletion.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCompletion.cs
@@ -1,6 +1,6 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
index 0e2108f0f2..66d2a66f99 100644
--- a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
@@ -1,6 +1,6 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/src/csharp/Grpc.Core/Internal/CStringSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CStringSafeHandle.cs
index 4ae57aa773..0221798d2a 100644
--- a/src/csharp/Grpc.Core/Internal/CStringSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CStringSafeHandle.cs
@@ -1,5 +1,5 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/src/csharp/Grpc.Core/Internal/CallCredentialsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallCredentialsSafeHandle.cs
index 0f36337f11..3095a34008 100644
--- a/src/csharp/Grpc.Core/Internal/CallCredentialsSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CallCredentialsSafeHandle.cs
@@ -1,5 +1,5 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
index bc045b67b1..500653ba5d 100644
--- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
@@ -1,5 +1,5 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs
index f6aa710b21..0038024245 100644
--- a/src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs
@@ -1,5 +1,5 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs
index 65cc2e019f..c85f55241a 100644
--- a/src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs
@@ -1,5 +1,5 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
index 2199905cc6..1dbd1f4e34 100644
--- a/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
@@ -1,5 +1,5 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/src/csharp/Grpc.Core/Internal/CompletionQueueEvent.cs b/src/csharp/Grpc.Core/Internal/CompletionQueueEvent.cs
index 36a92ecd8e..288680792a 100644
--- a/src/csharp/Grpc.Core/Internal/CompletionQueueEvent.cs
+++ b/src/csharp/Grpc.Core/Internal/CompletionQueueEvent.cs
@@ -1,6 +1,6 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs
index 9d7a990c42..91364cdc70 100644
--- a/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs
@@ -1,5 +1,5 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -101,7 +101,7 @@ namespace Grpc.Core.Internal
{
bool success = false;
shutdownRefcount.IncrementIfNonzero(ref success);
- Preconditions.CheckState(success, "Shutdown has already been called");
+ GrpcPreconditions.CheckState(success, "Shutdown has already been called");
}
private void EndOp()
diff --git a/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs b/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs
index 2796c959a3..628844f242 100644
--- a/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs
+++ b/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs
@@ -59,7 +59,7 @@ namespace Grpc.Core.Internal
public void Register(IntPtr key, OpCompletionDelegate callback)
{
environment.DebugStats.PendingBatchCompletions.Increment();
- Preconditions.CheckState(dict.TryAdd(key, callback));
+ GrpcPreconditions.CheckState(dict.TryAdd(key, callback));
}
public void RegisterBatchCompletion(BatchContextSafeHandle ctx, BatchCompletionDelegate callback)
@@ -71,7 +71,7 @@ namespace Grpc.Core.Internal
public OpCompletionDelegate Extract(IntPtr key)
{
OpCompletionDelegate value;
- Preconditions.CheckState(dict.TryRemove(key, out value));
+ GrpcPreconditions.CheckState(dict.TryRemove(key, out value));
environment.DebugStats.PendingBatchCompletions.Decrement();
return value;
}
diff --git a/src/csharp/Grpc.Core/Internal/DefaultSslRootsOverride.cs b/src/csharp/Grpc.Core/Internal/DefaultSslRootsOverride.cs
index eeaa7add81..aa4dafd7f2 100644
--- a/src/csharp/Grpc.Core/Internal/DefaultSslRootsOverride.cs
+++ b/src/csharp/Grpc.Core/Internal/DefaultSslRootsOverride.cs
@@ -1,6 +1,6 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -56,7 +56,7 @@ namespace Grpc.Core.Internal
{
lock (staticLock)
{
- var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(RootsPemResourceName);
+ var stream = typeof(DefaultSslRootsOverride).GetTypeInfo().Assembly.GetManifestResourceStream(RootsPemResourceName);
if (stream == null)
{
throw new IOException(string.Format("Error loading the embedded resource \"{0}\"", RootsPemResourceName));
diff --git a/src/csharp/Grpc.Core/Internal/Enums.cs b/src/csharp/Grpc.Core/Internal/Enums.cs
index b0eab2001b..74f86d2a30 100644
--- a/src/csharp/Grpc.Core/Internal/Enums.cs
+++ b/src/csharp/Grpc.Core/Internal/Enums.cs
@@ -72,7 +72,7 @@ namespace Grpc.Core.Internal
/// </summary>
public static void CheckOk(this GRPCCallError callError)
{
- Preconditions.CheckState(callError == GRPCCallError.OK, "Call error: " + callError);
+ GrpcPreconditions.CheckState(callError == GRPCCallError.OK, "Call error: " + callError);
}
}
diff --git a/src/csharp/Grpc.Core/Internal/InterceptingCallInvoker.cs b/src/csharp/Grpc.Core/Internal/InterceptingCallInvoker.cs
new file mode 100644
index 0000000000..ef48dc7121
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/InterceptingCallInvoker.cs
@@ -0,0 +1,134 @@
+#region Copyright notice and license
+
+// Copyright 2015-2016, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Utils;
+
+namespace Grpc.Core.Internal
+{
+ /// <summary>
+ /// Decorates an underlying <c>CallInvoker</c> to intercept call invocations.
+ /// </summary>
+ internal class InterceptingCallInvoker : CallInvoker
+ {
+ readonly CallInvoker callInvoker;
+ readonly Func<string, string> hostInterceptor;
+ readonly Func<CallOptions, CallOptions> callOptionsInterceptor;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Grpc.Core.InterceptingCallInvoker"/> class.
+ /// </summary>
+ public InterceptingCallInvoker(CallInvoker callInvoker,
+ Func<string, string> hostInterceptor = null,
+ Func<CallOptions, CallOptions> callOptionsInterceptor = null)
+ {
+ this.callInvoker = GrpcPreconditions.CheckNotNull(callInvoker);
+ this.hostInterceptor = hostInterceptor;
+ this.callOptionsInterceptor = callOptionsInterceptor;
+ }
+
+ /// <summary>
+ /// Intercepts a unary call.
+ /// </summary>
+ public override TResponse BlockingUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
+ {
+ host = InterceptHost(host);
+ options = InterceptCallOptions(options);
+ return callInvoker.BlockingUnaryCall(method, host, options, request);
+ }
+
+ /// <summary>
+ /// Invokes a simple remote call asynchronously.
+ /// </summary>
+ public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
+ {
+ host = InterceptHost(host);
+ options = InterceptCallOptions(options);
+ return callInvoker.AsyncUnaryCall(method, host, options, request);
+ }
+
+ /// <summary>
+ /// Invokes a server streaming call asynchronously.
+ /// In server streaming scenario, client sends on request and server responds with a stream of responses.
+ /// </summary>
+ public override AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
+ {
+ host = InterceptHost(host);
+ options = InterceptCallOptions(options);
+ return callInvoker.AsyncServerStreamingCall(method, host, options, request);
+ }
+
+ /// <summary>
+ /// Invokes a client streaming call asynchronously.
+ /// In client streaming scenario, client sends a stream of requests and server responds with a single response.
+ /// </summary>
+ public override AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
+ {
+ host = InterceptHost(host);
+ options = InterceptCallOptions(options);
+ return callInvoker.AsyncClientStreamingCall(method, host, options);
+ }
+
+ /// <summary>
+ /// Invokes a duplex streaming call asynchronously.
+ /// In duplex streaming scenario, client sends a stream of requests and server responds with a stream of responses.
+ /// The response stream is completely independent and both side can be sending messages at the same time.
+ /// </summary>
+ public override AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
+ {
+ host = InterceptHost(host);
+ options = InterceptCallOptions(options);
+ return callInvoker.AsyncDuplexStreamingCall(method, host, options);
+ }
+
+ private string InterceptHost(string host)
+ {
+ if (hostInterceptor == null)
+ {
+ return host;
+ }
+ return hostInterceptor(host);
+ }
+
+ private CallOptions InterceptCallOptions(CallOptions options)
+ {
+ if (callOptionsInterceptor == null)
+ {
+ return options;
+ }
+ return callOptionsInterceptor(options);
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs b/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs
index 81760d7a10..25735d5262 100644
--- a/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs
@@ -1,5 +1,5 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/src/csharp/Grpc.Core/Internal/NativeExtension.cs b/src/csharp/Grpc.Core/Internal/NativeExtension.cs
index e14d33ea50..bff1e56582 100644
--- a/src/csharp/Grpc.Core/Internal/NativeExtension.cs
+++ b/src/csharp/Grpc.Core/Internal/NativeExtension.cs
@@ -1,6 +1,6 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -32,6 +32,7 @@
#endregion
using System;
+using System.Globalization;
using System.IO;
using System.Reflection;
@@ -99,14 +100,30 @@ namespace Grpc.Core.Internal
// TODO: allow customizing path to native extension (possibly through exposing a GrpcEnvironment property).
var libraryFlavor = string.Format("{0}_{1}", GetPlatformString(), GetArchitectureString());
- var fullPath = Path.Combine(GetExecutingAssemblyDirectory(),
+ var fullPath = Path.Combine(Path.GetDirectoryName(GetAssemblyPath()),
NativeLibrariesDir, libraryFlavor, GetNativeLibraryFilename());
return new UnmanagedLibrary(fullPath);
}
- private static string GetExecutingAssemblyDirectory()
+ private static string GetAssemblyPath()
{
- return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+ var assembly = typeof(NativeExtension).GetTypeInfo().Assembly;
+
+ // If assembly is shadowed (e.g. in a webapp), EscapedCodeBase is pointing
+ // to the original location of the assembly, and Location is pointing
+ // to the shadow copy. We care about the original location because
+ // the native dlls don't get shadowed.
+ var escapedCodeBase = assembly.EscapedCodeBase;
+ if (IsFileUri(escapedCodeBase))
+ {
+ return new Uri(escapedCodeBase).LocalPath;
+ }
+ return assembly.Location;
+ }
+
+ private static bool IsFileUri(string uri)
+ {
+ return uri.ToLowerInvariant().StartsWith(Uri.UriSchemeFile);
}
private static string GetPlatformString()
diff --git a/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs b/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs
index 4bbbb4808c..3fcf8673ee 100644
--- a/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs
+++ b/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs
@@ -1,6 +1,6 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs b/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs
index 36b865c09c..0e4d9070d3 100644
--- a/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs
+++ b/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs
@@ -1,5 +1,5 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -53,7 +53,7 @@ namespace Grpc.Core.Internal
public NativeMetadataCredentialsPlugin(AsyncAuthInterceptor interceptor)
{
- this.interceptor = Preconditions.CheckNotNull(interceptor, "interceptor");
+ this.interceptor = GrpcPreconditions.CheckNotNull(interceptor, "interceptor");
this.nativeInterceptor = NativeMetadataInterceptorHandler;
// Make sure the callback doesn't get garbage collected until it is destroyed.
diff --git a/src/csharp/Grpc.Core/Internal/NativeMethods.cs b/src/csharp/Grpc.Core/Internal/NativeMethods.cs
index 19a573581e..9ee0ba3bc0 100644
--- a/src/csharp/Grpc.Core/Internal/NativeMethods.cs
+++ b/src/csharp/Grpc.Core/Internal/NativeMethods.cs
@@ -1,6 +1,6 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/src/csharp/Grpc.Core/Internal/PlatformApis.cs b/src/csharp/Grpc.Core/Internal/PlatformApis.cs
index f0c5b0f63f..5d8c44b589 100644
--- a/src/csharp/Grpc.Core/Internal/PlatformApis.cs
+++ b/src/csharp/Grpc.Core/Internal/PlatformApis.cs
@@ -1,6 +1,6 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -53,12 +53,18 @@ namespace Grpc.Core.Internal
static PlatformApis()
{
+#if DNXCORE50
+ isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
+ isMacOSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
+ isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
+#else
var platform = Environment.OSVersion.Platform;
// PlatformID.MacOSX is never returned, commonly used trick is to identify Mac is by using uname.
isMacOSX = (platform == PlatformID.Unix && GetUname() == "Darwin");
isLinux = (platform == PlatformID.Unix && !isMacOSX);
isWindows = (platform == PlatformID.Win32NT || platform == PlatformID.Win32S || platform == PlatformID.Win32Windows);
+#endif
isMono = Type.GetType("Mono.Runtime") != null;
}
diff --git a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
index de66759b94..1f83e51548 100644
--- a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
@@ -78,10 +78,10 @@ namespace Grpc.Core.Internal
var context = HandlerUtils.NewContext(newRpc, asyncCall.Peer, responseStream, asyncCall.CancellationToken);
try
{
- Preconditions.CheckArgument(await requestStream.MoveNext().ConfigureAwait(false));
+ GrpcPreconditions.CheckArgument(await requestStream.MoveNext().ConfigureAwait(false));
var request = requestStream.Current;
// TODO(jtattermusch): we need to read the full stream so that native callhandle gets deallocated.
- Preconditions.CheckArgument(!await requestStream.MoveNext().ConfigureAwait(false));
+ GrpcPreconditions.CheckArgument(!await requestStream.MoveNext().ConfigureAwait(false));
var result = await handler(request, context).ConfigureAwait(false);
status = context.Status;
await responseStream.WriteAsync(result).ConfigureAwait(false);
@@ -134,10 +134,10 @@ namespace Grpc.Core.Internal
var context = HandlerUtils.NewContext(newRpc, asyncCall.Peer, responseStream, asyncCall.CancellationToken);
try
{
- Preconditions.CheckArgument(await requestStream.MoveNext().ConfigureAwait(false));
+ GrpcPreconditions.CheckArgument(await requestStream.MoveNext().ConfigureAwait(false));
var request = requestStream.Current;
// TODO(jtattermusch): we need to read the full stream so that native callhandle gets deallocated.
- Preconditions.CheckArgument(!await requestStream.MoveNext().ConfigureAwait(false));
+ GrpcPreconditions.CheckArgument(!await requestStream.MoveNext().ConfigureAwait(false));
await handler(request, responseStream, context).ConfigureAwait(false);
status = context.Status;
}
diff --git a/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs
index a1d080c7f1..24f686fddc 100644
--- a/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs
@@ -1,5 +1,5 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -49,7 +49,7 @@ namespace Grpc.Core.Internal
public static ServerCredentialsSafeHandle CreateSslCredentials(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, bool forceClientAuth)
{
- Preconditions.CheckArgument(keyCertPairCertChainArray.Length == keyCertPairPrivateKeyArray.Length);
+ GrpcPreconditions.CheckArgument(keyCertPairCertChainArray.Length == keyCertPairPrivateKeyArray.Length);
return Native.grpcsharp_ssl_server_credentials_create(pemRootCerts,
keyCertPairCertChainArray, keyCertPairPrivateKeyArray,
new UIntPtr((ulong)keyCertPairCertChainArray.Length),
diff --git a/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
index a57fb3b789..6b5f70e220 100644
--- a/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
@@ -1,6 +1,6 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
diff --git a/src/csharp/Grpc.Core/Internal/Timespec.cs b/src/csharp/Grpc.Core/Internal/Timespec.cs
index 148d877da5..56172a5dda 100644
--- a/src/csharp/Grpc.Core/Internal/Timespec.cs
+++ b/src/csharp/Grpc.Core/Internal/Timespec.cs
@@ -1,5 +1,5 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -141,8 +141,8 @@ namespace Grpc.Core.Internal
/// </summary>
public DateTime ToDateTime()
{
- Preconditions.CheckState(tv_nsec >= 0 && tv_nsec < NanosPerSecond);
- Preconditions.CheckState(clock_type == GPRClockType.Realtime);
+ GrpcPreconditions.CheckState(tv_nsec >= 0 && tv_nsec < NanosPerSecond);
+ GrpcPreconditions.CheckState(clock_type == GPRClockType.Realtime);
// fast path for InfFuture
if (this.Equals(InfFuture))
@@ -195,7 +195,7 @@ namespace Grpc.Core.Internal
return Timespec.InfPast;
}
- Preconditions.CheckArgument(dateTime.Kind == DateTimeKind.Utc, "dateTime needs of kind DateTimeKind.Utc or be equal to DateTime.MaxValue or DateTime.MinValue.");
+ GrpcPreconditions.CheckArgument(dateTime.Kind == DateTimeKind.Utc, "dateTime needs of kind DateTimeKind.Utc or be equal to DateTime.MaxValue or DateTime.MinValue.");
try
{
diff --git a/src/csharp/Grpc.Core/Internal/UnimplementedCallInvoker.cs b/src/csharp/Grpc.Core/Internal/UnimplementedCallInvoker.cs
new file mode 100644
index 0000000000..0c7340873b
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/UnimplementedCallInvoker.cs
@@ -0,0 +1,75 @@
+#region Copyright notice and license
+
+// Copyright 2015-2016, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Utils;
+
+namespace Grpc.Core.Internal
+{
+ /// <summary>
+ /// Call invoker that throws <c>NotImplementedException</c> for all requests.
+ /// </summary>
+ internal class UnimplementedCallInvoker : CallInvoker
+ {
+ public UnimplementedCallInvoker()
+ {
+ }
+
+ public override TResponse BlockingUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs
index 95a8797e3e..47308f8c9e 100644
--- a/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs
+++ b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs
@@ -1,6 +1,6 @@
#region Copyright notice and license
-// Copyright 2015-2016, Google Inc.
+// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -65,7 +65,7 @@ namespace Grpc.Core.Internal
public UnmanagedLibrary(string libraryPath)
{
- this.libraryPath = Preconditions.CheckNotNull(libraryPath);
+ this.libraryPath = GrpcPreconditions.CheckNotNull(libraryPath);
if (!File.Exists(this.libraryPath))
{