From feadc3e4cce2d3b8e809804fd8f1a64580aae51f Mon Sep 17 00:00:00 2001 From: Ingo Bauersachs Date: Sat, 21 Dec 2013 15:17:47 +0100 Subject: [PATCH] Prevent deadlock if a XMPP certificate validation fails --- .../OperationSetPersistentPresenceJabberImpl.java | 10 +++++++--- .../jabber/ProtocolProviderServiceJabberImpl.java | 11 ++++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetPersistentPresenceJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetPersistentPresenceJabberImpl.java index 9dbc90bb5..ffe410396 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetPersistentPresenceJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetPersistentPresenceJabberImpl.java @@ -962,10 +962,14 @@ else if(evt.getNewState() == RegistrationState.UNREGISTERED ssContactList.cleanup(); subscribtionPacketListener = null; - if(parentProvider.getConnection() != null && - parentProvider.getConnection().getRoster() != null) - parentProvider.getConnection().getRoster() + XMPPConnection connection = parentProvider.getConnection(); + if(connection != null) + { + // the roster is guaranteed to be non-null + connection.getRoster() .removeRosterListener(contactChangesListener); + } + contactChangesListener = null; } } diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java index b664ec24b..d74c07e27 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java @@ -2433,10 +2433,19 @@ public void checkServerTrusted(X509Certificate[] chain, String authType) } catch(CertificateException e) { - fireRegistrationStateChanged(getRegistrationState(), + // notify in a separate thread to avoid a deadlock when a + // reg state listener accesses a synchronized XMPPConnection + // method (like getRoster) + new Thread(new Runnable() + { + public void run() + { + fireRegistrationStateChanged(getRegistrationState(), RegistrationState.UNREGISTERED, RegistrationStateChangeEvent.REASON_USER_REQUEST, "Not trusted certificate"); + } + }).start(); throw e; }