Skip to content

Commit d1c53ef

Browse files
authored
Fix TWMC when using single threaded sync context (#5136)
1 parent 2ae3e51 commit d1c53ef

File tree

2 files changed

+27
-14
lines changed

2 files changed

+27
-14
lines changed

src/System.Private.ServiceModel/tests/Scenarios/Binding/WS/TransportWithMessageCredentialSecurity/WSNetTcpTransportWithMessageCredentialSecurityTests.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
using System.ServiceModel;
88
using System.ServiceModel.Channels;
99
using System.ServiceModel.Security;
10+
using System.Threading;
11+
using System.Threading.Tasks;
1012
using Infrastructure.Common;
1113
using Xunit;
1214

@@ -108,4 +110,21 @@ public static void NetTcp_SecModeTransWithMessCred_UserNameClientCredential_Succ
108110
ScenarioTestHelpers.CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
109111
}
110112
}
113+
114+
[WcfFact]
115+
[Issue(2870, OS = OSID.OSX)]
116+
[Condition(nameof(Root_Certificate_Installed),
117+
nameof(SSL_Available))]
118+
[OuterLoop]
119+
public static void NetTcp_SecModeTransWithMessCred_UserNameClientCredential_Succeeds_WithSingleThreadedSyncContext()
120+
{
121+
bool success = Task.Run(() =>
122+
{
123+
TestTypes.SingleThreadSynchronizationContext.Run(() =>
124+
{
125+
Task.Factory.StartNew(() => NetTcp_SecModeTransWithMessCred_UserNameClientCredential_Succeeds(), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext()).Wait();
126+
});
127+
}).Wait(ScenarioTestHelpers.TestTimeout * 10000);
128+
Assert.True(success, "Test Scenario: NetTcp_SecModeTransWithMessCred_UserNameClientCredential_Succeeds_WithSingleThreadedSyncContext timed-out.");
129+
}
111130
}

src/System.ServiceModel.Primitives/src/System/ServiceModel/Security/SecuritySessionClientSettings.cs

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,11 +1466,11 @@ public Task<Message> RequestAsync(Message message)
14661466

14671467
Message IRequestChannel.Request(Message message) => ((IRequestChannel)this).Request(message, DefaultSendTimeout);
14681468

1469-
Message IRequestChannel.Request(Message message, TimeSpan timeout) => RequestAsyncInternal(message, timeout).WaitForCompletionNoSpin();
1469+
Message IRequestChannel.Request(Message message, TimeSpan timeout) => RequestAsync(message, timeout).WaitForCompletionNoSpin();
14701470

14711471
IAsyncResult IRequestChannel.BeginRequest(Message message, AsyncCallback callback, object state) => ((IRequestChannel)this).BeginRequest(message, DefaultSendTimeout, callback, state);
14721472

1473-
IAsyncResult IRequestChannel.BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state) => RequestAsyncInternal(message, timeout).ToApm(callback, state);
1473+
IAsyncResult IRequestChannel.BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state) => RequestAsync(message, timeout).ToApm(callback, state);
14741474

14751475
Message IRequestChannel.EndRequest(IAsyncResult result) => result.ToApmEnd<Message>();
14761476

@@ -1515,18 +1515,13 @@ private Message ProcessReply(Message reply, TimeSpan timeout, SecurityProtocolCo
15151515
return processedReply;
15161516
}
15171517

1518-
private async Task<Message> RequestAsyncInternal(Message message, TimeSpan timeout)
1519-
{
1520-
await TaskHelpers.EnsureDefaultTaskScheduler();
1521-
return await RequestAsync(message, timeout);
1522-
}
1523-
15241518
public async Task<Message> RequestAsync(Message message, TimeSpan timeout)
15251519
{
15261520
ThrowIfFaulted();
15271521
CheckOutputOpen();
15281522
TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
15291523
SecurityProtocolCorrelationState correlationState;
1524+
await TaskHelpers.EnsureDefaultTaskScheduler();
15301525
(correlationState, message) = await SecureOutgoingMessageAsync(message, timeoutHelper.RemainingTime());
15311526
Message reply = await ChannelBinder.RequestAsync(message, timeoutHelper.RemainingTime());
15321527
return ProcessReply(reply, timeoutHelper.RemainingTime(), correlationState);
@@ -1618,6 +1613,7 @@ public bool TryReceive(TimeSpan timeout, out Message message)
16181613
public async Task<(bool, Message)> TryReceiveAsync(TimeSpan timeout)
16191614
{
16201615
ThrowIfFaulted();
1616+
await TaskHelpers.EnsureDefaultTaskScheduler();
16211617
(bool wasDequeued, Message message) = await _queue.TryDequeueAsync(timeout);
16221618
if (message == null)
16231619
{
@@ -1627,21 +1623,19 @@ public bool TryReceive(TimeSpan timeout, out Message message)
16271623
return (wasDequeued, message);
16281624
}
16291625

1630-
public void Send(Message message) => SendAsync(message).GetAwaiter().GetResult();
1626+
public void Send(Message message) => SendAsync(message).WaitForCompletionNoSpin();
16311627

1632-
public Task SendAsync(Message message)
1633-
{
1634-
return SendAsync(message, DefaultSendTimeout);
1635-
}
1628+
public Task SendAsync(Message message) => SendAsync(message, DefaultSendTimeout);
16361629

1637-
public void Send(Message message, TimeSpan timeout) => SendAsync(message, timeout).GetAwaiter().GetResult();
1630+
public void Send(Message message, TimeSpan timeout) => SendAsync(message, timeout).WaitForCompletionNoSpin();
16381631

16391632
public async Task SendAsync(Message message, TimeSpan timeout)
16401633
{
16411634
ThrowIfFaulted();
16421635
CheckOutputOpen();
16431636
TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
16441637
SecurityProtocolCorrelationState dummy;
1638+
await TaskHelpers.EnsureDefaultTaskScheduler();
16451639
(dummy, message) = await SecureOutgoingMessageAsync(message, timeoutHelper.RemainingTime());
16461640
await ChannelBinder.SendAsync(message, timeoutHelper.RemainingTime());
16471641
}

0 commit comments

Comments
 (0)