diff --git a/resources/languages/resources.properties b/resources/languages/resources.properties
index e5e843459..06b9aaff2 100644
--- a/resources/languages/resources.properties
+++ b/resources/languages/resources.properties
@@ -943,4 +943,4 @@ plugin.globalproxy.PROTOCOL_SUPPORT=
\
# plugin reconnect
plugin.reconnectplugin.CONNECTION_FAILED_MSG=Connection failed for the following account:\nUser name: {0}, Server name: {1}.\nPlease check your settings or contact your network administrator for more information.
-plugin.reconnectplugin.NETWORK_DOWN=Network is down!
+plugin.reconnectplugin.NETWORK_DOWN=Network connectivity lost!
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 5c42e4d82..478fcfab5 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java
@@ -169,6 +169,22 @@ public class ProtocolProviderServiceJabberImpl
*/
private boolean certChecked = false;
+ /**
+ * Flag indicating are we currently executing connectAndLogin method.
+ */
+ private boolean inConnectAndLogin = false;
+
+ /**
+ * Object used to synchronize the flag inConnectAndLogin.
+ */
+ private final Object connectAndLoginLock = new Object();
+
+ /**
+ * If an event occurs during login we fire it at the end of the login
+ * process (at the end of connectAndLogin method).
+ */
+ private RegistrationStateChangeEvent eventDuringLogin = null;
+
/**
* Returns the state of the registration of this protocol provider
* @return the RegistrationState that this provider is
@@ -293,6 +309,11 @@ private synchronized void connectAndLogin(SecurityAuthority authority,
int reasonCode)
throws XMPPException, OperationFailedException
{
+ synchronized(connectAndLoginLock)
+ {
+ inConnectAndLogin = true;
+ }
+
synchronized(initializationLock)
{
//verify whether a password has already been stored for this account
@@ -591,6 +612,30 @@ else if(globalProxyType.equals(
OperationFailedException.INVALID_ACCOUNT_PROPERTIES, ex);
}
}
+
+ synchronized(connectAndLoginLock)
+ {
+ // Checks if an error has occured during login, if so we fire
+ // it here in order to avoid a deadlock which occurs in
+ // reconnect plugin. The deadlock is cause we fired an event during
+ // login process and have locked initializationLock and we cannot
+ // unregister from reconnect, cause unregister method
+ // also needs this lock.
+ if(eventDuringLogin != null)
+ {
+ fireRegistrationStateChanged(
+ eventDuringLogin.getOldState(),
+ eventDuringLogin.getNewState(),
+ eventDuringLogin.getReasonCode(),
+ eventDuringLogin.getReason());
+
+ eventDuringLogin = null;
+ inConnectAndLogin = false;
+ return;
+ }
+
+ inConnectAndLogin = false;
+ }
}
/**
@@ -1004,6 +1049,23 @@ public void connectionClosedOnError(Exception exception)
if(err != null && err.getCode().equals(
XMPPError.Condition.conflict.toString()))
{
+ // if we are in the middle of connecting process
+ // do not fire events, will do it later when the method
+ // connectAndLogin finishes its work
+ synchronized(connectAndLoginLock)
+ {
+ if(inConnectAndLogin)
+ {
+ eventDuringLogin = new RegistrationStateChangeEvent(
+ ProtocolProviderServiceJabberImpl.this,
+ getRegistrationState(),
+ RegistrationState.CONNECTION_FAILED,
+ RegistrationStateChangeEvent.REASON_MULTIPLE_LOGINS,
+ "Connecting multiple times with the same resource");
+ return;
+ }
+ }
+
fireRegistrationStateChanged(getRegistrationState(),
RegistrationState.CONNECTION_FAILED,
RegistrationStateChangeEvent.REASON_MULTIPLE_LOGINS,
@@ -1017,6 +1079,23 @@ else if(exception instanceof SSLHandshakeException &&
return;
}
+ // if we are in the middle of connecting process
+ // do not fire events, will do it later when the method
+ // connectAndLogin finishes its work
+ synchronized(connectAndLoginLock)
+ {
+ if(inConnectAndLogin)
+ {
+ eventDuringLogin = new RegistrationStateChangeEvent(
+ ProtocolProviderServiceJabberImpl.this,
+ getRegistrationState(),
+ RegistrationState.CONNECTION_FAILED,
+ RegistrationStateChangeEvent.REASON_NOT_SPECIFIED,
+ exception.getMessage());
+ return;
+ }
+ }
+
fireRegistrationStateChanged(getRegistrationState(),
RegistrationState.CONNECTION_FAILED,
RegistrationStateChangeEvent.REASON_NOT_SPECIFIED,