Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/mcs
diff options
context:
space:
mode:
authorAlexander Köplinger <alex.koeplinger@outlook.com>2015-12-21 16:33:14 +0300
committerAlexander Köplinger <alex.koeplinger@outlook.com>2015-12-21 16:33:14 +0300
commit672cc6819815b0206d3f685c7379e00de916cd4d (patch)
tree5c21c5fd4fe508d5509255475d229628f96c8f4e /mcs
parentaaca175b4467ce44dcb8fd5260099148eb4e7284 (diff)
[ServiceModel] Make TcpReplyChannel.OnClose thread-safe
We were seeing the following unhandled exception on Jenkins: ```` Unhandled exceptions: 1) MonoTests.System.ServiceModel.OperationContextTest.Current : System.NullReferenceException: Object reference not set to an instance of an object at System.ServiceModel.Channels.NetTcp.TcpReplyChannel.OnClose (TimeSpan timeout) [0x00000] in /media/ssd/jenkins/workspace/test-mono-mainline/label/debian-armhf/mcs/class/System.ServiceModel/System.ServiceModel.Channels.NetTcp/TcpReplyChannel.cs:141 at System.ServiceModel.Channels.CommunicationObject.Close (TimeSpan timeout) [0x0001c] in /media/ssd/jenkins/workspace/test-mono-mainline/label/debian-armhf/mcs/class/System.ServiceModel/System.ServiceModel.Channels/CommunicationObject.cs:140 at System.ServiceModel.Channels.CommunicationObject.Close () [0x00000] in /media/ssd/jenkins/workspace/test-mono-mainline/label/debian-armhf/mcs/class/System.ServiceModel/System.ServiceModel.Channels/CommunicationObject.cs:131 at System.ServiceModel.Dispatcher.ListenerLoopManager.TryReceiveRequestDone (IAsyncResult result) [0x00027] in /media/ssd/jenkins/workspace/test-mono-mainline/label/debian-armhf/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ChannelDispatcher.cs:583 ``` This happens because multiple threads can call OnClose() and so `client` can be null. Fixed this by taking code from HttpReplyChannel.OnClose which handled this already and also fixed the race condition there (the checks need to happen under a lock).
Diffstat (limited to 'mcs')
-rw-r--r--mcs/class/System.ServiceModel/System.ServiceModel.Channels.Http/HttpReplyChannel.cs9
-rw-r--r--mcs/class/System.ServiceModel/System.ServiceModel.Channels.NetTcp/TcpReplyChannel.cs9
2 files changed, 15 insertions, 3 deletions
diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels.Http/HttpReplyChannel.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels.Http/HttpReplyChannel.cs
index 03e7cad1f1c..098b622aa83 100644
--- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels.Http/HttpReplyChannel.cs
+++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels.Http/HttpReplyChannel.cs
@@ -104,12 +104,15 @@ namespace System.ServiceModel.Channels.Http
}
bool close_started;
+ object close_lock = new object ();
protected override void OnClose (TimeSpan timeout)
{
- if (close_started)
- return;
- close_started = true;
+ lock (close_lock) {
+ if (close_started)
+ return;
+ close_started = true;
+ }
DateTime start = DateTime.Now;
// FIXME: consider timeout
diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels.NetTcp/TcpReplyChannel.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels.NetTcp/TcpReplyChannel.cs
index f597167e9d1..b005ad6c18a 100644
--- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels.NetTcp/TcpReplyChannel.cs
+++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels.NetTcp/TcpReplyChannel.cs
@@ -135,9 +135,18 @@ namespace System.ServiceModel.Channels.NetTcp
{
throw new NotImplementedException ();
}
+
+ bool close_started;
+ object close_lock = new object ();
protected override void OnClose (TimeSpan timeout)
{
+ lock (close_lock) {
+ if (close_started)
+ return;
+ close_started = true;
+ }
+
client.Close ();
client = null;
base.OnClose (timeout);