migutica / jabber-net

Automatically exported from code.google.com/p/jabber-net
Other
0 stars 0 forks source link

JabberClient does not dispose properly #99

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Calling JabberClient.Close or dereferencing instances do not allow the
object to cleanup after itself. Sockets may be left open, memory is
consumed, streams can be left open.  Below are 5 areas I made changes to
allow the objects to properly dispose. This only serves as a starting point
to address this issue.  My use case was pretty simple Socket based
connections with no compression, encryption, etc.

1.
AsyncSocket.Close
 if (m_stream != null)
                    m_stream.Close();
                else
needs a m_sock.Close() above the m_stream.Close().  Closing the
networkstream will not close the underlying socket because when it is
instantiated ownsSocket is not set to true

2.
~AsyncSocket()
        {
                m_pending.Close();
            m_pending = null;
        }

Cleanup memory stream in destructor. 

3. Add interface IDisposable to SocketStanza Stream
         public  void Dispose()
        {
            m_timer.Dispose();
            m_timer = null;

            m_elements.OnDocumentStart -= new
ProtocolHandler(m_elements_OnDocumentStart);
            m_elements.OnDocumentEnd -= new
bedrock.ObjectHandler(m_elements_OnDocumentEnd);
            m_elements.OnElement -= new ProtocolHandler(m_elements_OnElement);
            m_elements.OnError -= new
bedrock.ExceptionHandler(m_elements_OnError);
            m_elements = null;

        }

4. Catch all m_timer calls when m_timer may now be null

5. In XmppStream.Errored and .Closed change
if ((m_stanzas != null) && (!m_stanzas.Acceptable))
                    m_stanzas = null;

to

                if ((m_stanzas != null) && (!m_stanzas.Acceptable))  //JAK
Added shutdown logic
                {
                    try
                    {
                            if (m_stanzas != null)
                            {
                                if (m_stanzas.Connected)
                                {
                                    m_stanzas.Close(false);
                                }
                                if (m_stanzas is IDisposable)
                                {
                                    IDisposable disposable =
(IDisposable)m_stanzas;
                                    disposable.Dispose();
                                }
                            }
                    }
                    catch { }
                    m_stanzas = null;
                }

Original issue reported on code.google.com by jk...@tricomsystems.net on 30 Mar 2010 at 1:43