Fix a deadlock occurring for jabber accounts, which during login fire connection failed.

cusax-fix
Damian Minkov 16 years ago
parent 34d50ba2aa
commit 157458af69

@ -943,4 +943,4 @@ plugin.globalproxy.PROTOCOL_SUPPORT=<html><table> \
# 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!

@ -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 <tt>RegistrationState</tt> 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,

Loading…
Cancel
Save