aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/csharp/Grpc.Core
diff options
context:
space:
mode:
Diffstat (limited to 'src/csharp/Grpc.Core')
-rw-r--r--src/csharp/Grpc.Core/Grpc.Core.csproj4
-rw-r--r--src/csharp/Grpc.Core/GrpcEnvironment.cs16
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCall.cs6
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCallBase.cs5
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCallServer.cs6
-rw-r--r--src/csharp/Grpc.Core/Internal/AtomicCounter.cs61
-rw-r--r--src/csharp/Grpc.Core/Internal/DebugStats.cs45
7 files changed, 142 insertions, 1 deletions
diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj
index fee742b220..9c91541d90 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.csproj
+++ b/src/csharp/Grpc.Core/Grpc.Core.csproj
@@ -5,7 +5,7 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>10.0.0</ProductVersion>
+ <ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</ProjectGuid>
<OutputType>Library</OutputType>
@@ -94,6 +94,8 @@
<Compile Include="Internal\ClientResponseStream.cs" />
<Compile Include="Internal\ServerRequestStream.cs" />
<Compile Include="Internal\ServerResponseStream.cs" />
+ <Compile Include="Internal\AtomicCounter.cs" />
+ <Compile Include="Internal\DebugStats.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
diff --git a/src/csharp/Grpc.Core/GrpcEnvironment.cs b/src/csharp/Grpc.Core/GrpcEnvironment.cs
index 9c10a42e23..2e9e5a2ef6 100644
--- a/src/csharp/Grpc.Core/GrpcEnvironment.cs
+++ b/src/csharp/Grpc.Core/GrpcEnvironment.cs
@@ -86,6 +86,8 @@ namespace Grpc.Core
{
instance.Close();
instance = null;
+
+ CheckDebugStats();
}
}
}
@@ -132,5 +134,19 @@ namespace Grpc.Core
// TODO: use proper logging here
Console.WriteLine("GRPC shutdown.");
}
+
+ private static void CheckDebugStats()
+ {
+ var remainingClientCalls = DebugStats.ActiveClientCalls.Count;
+ if (remainingClientCalls != 0)
+ {
+ Console.WriteLine("Warning: Detected {0} client calls that weren't disposed properly.", remainingClientCalls);
+ }
+ var remainingServerCalls = DebugStats.ActiveServerCalls.Count;
+ if (remainingServerCalls != 0)
+ {
+ Console.WriteLine("Warning: Detected {0} server calls that weren't disposed properly.", remainingServerCalls);
+ }
+ }
}
}
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
index fd94771ddd..3532f7347a 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
@@ -67,6 +67,7 @@ namespace Grpc.Core.Internal
public void Initialize(Channel channel, CompletionQueueSafeHandle cq, string methodName)
{
var call = CallSafeHandle.Create(channel.Handle, cq, methodName, channel.Target, Timespec.InfFuture);
+ DebugStats.ActiveClientCalls.Increment();
InitializeInternal(call);
}
@@ -265,6 +266,11 @@ namespace Grpc.Core.Internal
}
}
+ protected override void OnReleaseResources()
+ {
+ DebugStats.ActiveClientCalls.Decrement();
+ }
+
/// <summary>
/// Handler for unary response completion.
/// </summary>
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
index 2bde4b3720..b911cdcc87 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
@@ -191,6 +191,7 @@ namespace Grpc.Core.Internal
private void ReleaseResources()
{
+ OnReleaseResources();
if (call != null)
{
call.Dispose();
@@ -199,6 +200,10 @@ namespace Grpc.Core.Internal
disposed = true;
}
+ protected virtual void OnReleaseResources()
+ {
+ }
+
protected void CheckSendingAllowed()
{
Preconditions.CheckState(started);
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
index 449009336f..4775f2d07b 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
@@ -57,6 +57,7 @@ namespace Grpc.Core.Internal
public void Initialize(CallSafeHandle call)
{
+ DebugStats.ActiveServerCalls.Increment();
InitializeInternal(call);
}
@@ -112,6 +113,11 @@ namespace Grpc.Core.Internal
}
}
+ protected override void OnReleaseResources()
+ {
+ DebugStats.ActiveServerCalls.Decrement();
+ }
+
/// <summary>
/// Handles the server side close completion.
/// </summary>
diff --git a/src/csharp/Grpc.Core/Internal/AtomicCounter.cs b/src/csharp/Grpc.Core/Internal/AtomicCounter.cs
new file mode 100644
index 0000000000..7ccda225dc
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/AtomicCounter.cs
@@ -0,0 +1,61 @@
+#region Copyright notice and license
+
+// Copyright 2015, 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;
+
+namespace Grpc.Core.Internal
+{
+ internal class AtomicCounter
+ {
+ long counter = 0;
+
+ public void Increment()
+ {
+ Interlocked.Increment(ref counter);
+ }
+
+ public void Decrement()
+ {
+ Interlocked.Decrement(ref counter);
+ }
+
+ public long Count
+ {
+ get
+ {
+ return counter;
+ }
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Internal/DebugStats.cs b/src/csharp/Grpc.Core/Internal/DebugStats.cs
new file mode 100644
index 0000000000..476914f751
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/DebugStats.cs
@@ -0,0 +1,45 @@
+#region Copyright notice and license
+
+// Copyright 2015, 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;
+
+namespace Grpc.Core.Internal
+{
+ internal static class DebugStats
+ {
+ public static readonly AtomicCounter ActiveClientCalls = new AtomicCounter();
+
+ public static readonly AtomicCounter ActiveServerCalls = new AtomicCounter();
+ }
+}