-
Notifications
You must be signed in to change notification settings - Fork 13
Description
I've found an circular locking issue with the IStanzaEventListener methods in the XmppStream class .
Basically the IStanzaEventListener.StanzaReceived which acquires a [MethodImpl(MethodImplOptions.Synchronized)] lock can call IStanzaEventListener.BytesWritten which also needs to acquire a [MethodImpl(MethodImplOptions.Synchronized)] lock and therefore deadlocks.
The chain of calls is as follows:
XmppStream.StanzaReceived acquires a MethodImpl(MethodImplOptions.Synchronized) lock
--> calls XmppStream.OnElement
if (State is not ServerFeaturesState.Instance or SASLState.Instance or StartTLSState.Instance or CompressionState.Instance or SASLAuthedState.Instance)
--> invokes XmppStream.OnProtocol event
In IQTracker OnProtocol event is set to OnIQ
--> calls IQTracker.Call which calls the 'cb' callback which is set to JabberClient.GotSession in JabberClient.GotResource
--> sets JabberClient.IsAuthenticated
--> calls JabberClient.Presence
--> calls JabberClient.Write
--> calls SocketStanzaStream.JabberClient.Write
--> calls AsyncSocket.Write
--> calls Stream.BeginWrite with callback WroteData
--> WroteData calls SocketStanzaStream.OnWrite
--> calls XmppStream.BytesWritten which waits for a MethodImpl(MethodImplOptions.Synchronized) lock
Any ideas how to go about fixing this? The way this code uses callbacks is so convoluted its hard to know where to start without breaking something else.
The chain of events and subsequent deadlock is reproducible when sending a large number of XMPP messages.