diff --git a/Capnp.Net.Runtime.Tests/TcpRpcInterop.cs b/Capnp.Net.Runtime.Tests/TcpRpcInterop.cs index 051da1f..0726013 100644 --- a/Capnp.Net.Runtime.Tests/TcpRpcInterop.cs +++ b/Capnp.Net.Runtime.Tests/TcpRpcInterop.cs @@ -98,10 +98,7 @@ namespace Capnp.Net.Runtime.Tests [TestInitialize] public void PrepareNextTest() { - if (++TcpPort >= 65534) - { - TcpPort = 49152; - } + IncrementTcpPort(); } [TestMethod, Timeout(10000)] diff --git a/Capnp.Net.Runtime.Tests/TcpRpcPorted.cs b/Capnp.Net.Runtime.Tests/TcpRpcPorted.cs index 24afd14..9efddc0 100644 --- a/Capnp.Net.Runtime.Tests/TcpRpcPorted.cs +++ b/Capnp.Net.Runtime.Tests/TcpRpcPorted.cs @@ -8,6 +8,7 @@ using Capnp.Rpc; using Microsoft.VisualStudio.TestTools.UnitTesting; using Capnp.Net.Runtime.Tests.GenImpls; using Capnproto_test.Capnp.Test; +using Microsoft.Extensions.Logging; namespace Capnp.Net.Runtime.Tests { @@ -470,7 +471,17 @@ namespace Capnp.Net.Runtime.Tests var call4 = pipeline.GetCallSequence(4, default); var call5 = pipeline.GetCallSequence(5, default); - Assert.IsTrue(call0.Wait(MediumNonDbgTimeout)); + try + { + bool flag = call0.Wait(MediumNonDbgTimeout); + Assert.IsTrue(flag); + } + catch (RpcException exception) when (exception.Message == "Cannot access a disposed object.") + { + Logger.Log(LogLevel.Information, $"Oops, object disposed. Counter = {cap.Count}, tx count = {client.SendCount}, rx count = {client.RecvCount}"); + throw; + } + Assert.IsTrue(call1.Wait(MediumNonDbgTimeout)); Assert.IsTrue(call2.Wait(MediumNonDbgTimeout)); Assert.IsTrue(call3.Wait(MediumNonDbgTimeout)); diff --git a/Capnp.Net.Runtime.Tests/TcpRpcStress.cs b/Capnp.Net.Runtime.Tests/TcpRpcStress.cs index 4bc3e00..d45c45c 100644 --- a/Capnp.Net.Runtime.Tests/TcpRpcStress.cs +++ b/Capnp.Net.Runtime.Tests/TcpRpcStress.cs @@ -18,6 +18,7 @@ namespace Capnp.Net.Runtime.Tests for (int i = 0; i < count; i++) { Logger.LogTrace("Repetition {0}", i); + IncrementTcpPort(); action(); } } diff --git a/Capnp.Net.Runtime.Tests/TestBase.cs b/Capnp.Net.Runtime.Tests/TestBase.cs index ea13c1e..afdf1e0 100644 --- a/Capnp.Net.Runtime.Tests/TestBase.cs +++ b/Capnp.Net.Runtime.Tests/TestBase.cs @@ -18,13 +18,6 @@ namespace Capnp.Net.Runtime.Tests public static int LargeNonDbgTimeout => Debugger.IsAttached ? Timeout.Infinite : 20000; public static int ShortTimeout => 500; - public static int GetNextTcpPort() - { - if (++TcpPort == 65535) - TcpPort = 49152; - return TcpPort; - } - protected ILogger Logger { get; set; } protected TcpRpcClient SetupClient() => new TcpRpcClient("localhost", TcpPort); @@ -37,6 +30,14 @@ namespace Capnp.Net.Runtime.Tests return (server, client); } + public static void IncrementTcpPort() + { + if (++TcpPort > 49200) + { + TcpPort = 49152; + } + } + [TestInitialize] public void InitConsoleLogging() { diff --git a/Capnp.Net.Runtime/Rpc/TcpRpcServer.cs b/Capnp.Net.Runtime/Rpc/TcpRpcServer.cs index 8678ca1..d39bce1 100644 --- a/Capnp.Net.Runtime/Rpc/TcpRpcServer.cs +++ b/Capnp.Net.Runtime/Rpc/TcpRpcServer.cs @@ -193,19 +193,27 @@ namespace Capnp.Rpc try { - try + for (int retry = 0; retry < 5; ++retry) { - if (!_acceptorThread.Join(500)) + try { - Logger.LogError("Unable to join TCP acceptor thread within timeout"); + if (!_acceptorThread.Join(500)) + { + Logger.LogError("Unable to join TCP acceptor thread within timeout"); + } + break; + } + catch (ThreadStateException) + { + // In rare cases it happens that despite _acceptorThread.Start() was called, the thread did not actually start yet. + Logger.LogDebug("Waiting for TCP acceptor thread to start in order to join it"); + Thread.Sleep(100); + } + catch (System.Exception exception) + { + Logger.LogError($"Unable to join TCP acceptor thread: {exception.Message}"); + break; } - } - catch (ThreadStateException) - { - } - catch (System.Exception exception) - { - Logger.LogError($"Unable to join TCP acceptor thread: {exception.Message}"); } } catch (ThreadStateException)