1

Closed

[en] TcpEx: deadlock in Connection class

description

This deadlock may occur when the connection is broken.
It may result in application freezes on the client side.
Here is the code:
// line 67
public static Connection GetConnection(...)
{
     ...
     lock (_connectionsLockObject) // Monitor.Enter #1
     {
          ...
          channel.OnConnectionEstablished(EventArgs.Empty); // raise an event
     }
}

// line 482
public void Close()
{
     lock (_connectionsLockObject) // Monitor.Enter #2 on another thread, never returns
     {
        ...
     }
}
The first thread is holding the lock while waiting for an event:
// ClientTransportSink, line #88
public void ProcessMessage(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream, out ITransportHeaders responseHeaders, out Stream responseStream)
{
    if (requestStream.Length > int.MaxValue)
        throw new NotImplementedException("TcpEx Channel can only accept messages up to int.MaxValue in size."); // TODO: FixMe

    Connection connection = PrepareRequest(msg, ref requestHeaders);

    Guid msgGuid = Guid.NewGuid();
    IAsyncResult ar = Manager.BeginReadMessage(msgGuid, connection, null, null);
    Message.Send(connection, msgGuid, requestHeaders, requestStream); 

    ar.AsyncWaitHandle.WaitOne(); // <---- HERE
    Connection replyConnection;
    Message reply = Manager.EndReadMessage(out replyConnection, ar);
    Debug.Assert(connection == replyConnection);
    responseHeaders = reply.Headers;
    responseStream = reply.MessageBody;
}
ProcessMessage is called synchronously by ZyanConnection.ReconnectRemoteEvents,
which in turn is called by TcpExChannel.OnConnectionEstablished as an event handler.
Closed Aug 22, 2014 at 1:46 PM by yallie
Fixed, see changeset #42295.

comments