Fixes false reports on Windows that Jitsi has crashed.

cusax-fix 4880
Lyubomir Marinov 13 years ago
parent 41e8829b5b
commit d2fa11cd10

@ -7,21 +7,23 @@
package net.java.sip.communicator.impl.shutdowntimeout;
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.launchutils.*;
import org.osgi.framework.*;
/**
* In order to shut down SIP Communicator we kill the Felix system bundle.
* However, this sometimes doesn't work for reason of running non-daemon
* threads (such as the javasound event dispatcher). This results in having
* instances of SIP Communicator running in the background.
* In order to shut down Jitsi, we kill the Felix system bundle. However, this
* sometimes doesn't work for reason of running non-daemon threads (such as the
* Java Sound event dispatcher). This results in having instances of Jitsi
* running in the background.
*
* We use this shutdown timout bundle in order to fix this problem. When our
* We use this shutdown timeout bundle in order to fix this problem. When our
* stop method is called, we assume that a shutdown is executed and start a 15
* seconds daemon thread. If the application is still running once these 15
* seconds expire, we System.exit() the application.
*
* @author Emil Ivov
* @author Lyubomir Marinov
*/
public class ShutdownTimeout
implements BundleActivator
@ -32,25 +34,90 @@ public class ShutdownTimeout
/**
* The system property which can be used to set custom timeout.
*/
public static String SHUTDOWN_TIMEOUT_PROP =
"org.jitsi.shutdown.SHUTDOWN_TIMEOUT";
private static final String SHUTDOWN_TIMEOUT_PNAME
= "org.jitsi.shutdown.SHUTDOWN_TIMEOUT";
/**
* The number of miliseconds that we wait before we force a shutdown.
* The number of milliseconds that we wait before we force a shutdown.
*/
public static final long SHUTDOWN_TIMEOUT_DEFAULT = 5000;//ms
private static final long SHUTDOWN_TIMEOUT_DEFAULT = 5000;//ms
/**
* The code that we exit with if the application is not down in 15 seconds.
*/
public static final int SYSTEM_EXIT_CODE = 500;
private static final int SYSTEM_EXIT_CODE = 500;
/**
* Runs in a daemon thread started by {@link #stop(BundleContext)} and
* forcibly terminates the currently running Java virtual machine after
* {@link #SHUTDOWN_TIMEOUT_DEFAULT} (or {@link #SHUTDOWN_TIMEOUT_PNAME})
* milliseconds.
*/
private static void runInShutdownTimeoutThread()
{
long shutdownTimeout = SHUTDOWN_TIMEOUT_DEFAULT;
// Check for a custom value specified through a System property.
try
{
String s = System.getProperty(SHUTDOWN_TIMEOUT_PNAME);
if ((s != null) && (s.length() > 0))
{
long l = Long.valueOf(s);
// Make sure custom is not 0 to prevent waiting forever.
if (l > 0)
shutdownTimeout = l;
}
}
catch(Throwable t)
{
}
if (logger.isTraceEnabled())
{
logger.trace(
"Starting shutdown countdown of " + shutdownTimeout
+ "ms.");
}
try
{
Thread.sleep(shutdownTimeout);
}
catch (InterruptedException ex)
{
if (logger.isDebugEnabled())
logger.debug("Interrupted shutdown timer.");
return;
}
/*
* We are going to forcibly terminate the currently running Java virtual
* machine so it will not run DeleteOnExitHook. But the currently
* running Java virtual machine is still going to terminate because of
* our intention, not because it has crashed. Make sure that we delete
* any files registered for deletion when Runtime.halt(int) is to be
* invoked.
*/
try
{
DeleteOnHaltHook.runHooks();
}
catch (Throwable t)
{
logger.warn("Failed to delete files on halt.", t);
}
logger.error("Failed to gently shutdown. Forcing exit.");
Runtime.getRuntime().halt(SYSTEM_EXIT_CODE);
}
/**
* Dummy impl of the bundle activator start method.
*
* @param context unused
* @throws Exception If this method throws an exception
* (which won't happen).
* @throws Exception if this method throws an exception (which won't happen)
*/
public void start(BundleContext context)
throws Exception
@ -64,63 +131,26 @@ public void start(BundleContext context)
* bundle-specific activities necessary to stop the bundle.
*
* @param context The execution context of the bundle being stopped.
* @throws Exception If this method throws an exception, the bundle is
* still marked as stopped, and the Framework will remove the bundle's
* listeners, unregister all services registered by the bundle, and
* release all services used by the bundle.
* @throws Exception If this method throws an exception, the bundle is still
* marked as stopped, and the Framework will remove the bundle's listeners,
* unregister all services registered by the bundle, and release all
* services used by the bundle.
*/
public void stop(BundleContext context)
throws Exception
{
Thread shutdownTimeoutThread = new Thread()
{
@Override
public void run()
Thread shutdownTimeoutThread
= new Thread()
{
synchronized(this)
@Override
public void run()
{
try
{
long shutDownTimeout = SHUTDOWN_TIMEOUT_DEFAULT;
// check for custom value available through system
// property
try
{
String shutdownCustomValue =
System.getProperty(SHUTDOWN_TIMEOUT_PROP);
if(shutdownCustomValue != null
&& shutdownCustomValue.length() > 0)
{
long custom =
Long.valueOf(shutdownCustomValue);
// make sure custom is not 0, or it will
// wait forever
if(custom > 0)
shutDownTimeout = custom;
}
}
catch(Throwable t){}
if (logger.isTraceEnabled())
logger.trace("Starting shutdown countdown of "
+ shutDownTimeout + "ms.");
wait(shutDownTimeout);
logger.error("Failed to gently shutdown. Forcing exit.");
Runtime.getRuntime().halt(SYSTEM_EXIT_CODE);
}catch (InterruptedException ex){
if (logger.isDebugEnabled())
logger.debug("Interrupted shutdown timer.");
}
runInShutdownTimeoutThread();
}
}
};
if (logger.isTraceEnabled())
logger.trace("Created the shutdown timer thread.");
};
shutdownTimeoutThread.setDaemon(true);
shutdownTimeoutThread.setName(ShutdownTimeout.class.getName());
shutdownTimeoutThread.start();
}
}

@ -6,4 +6,5 @@ Bundle-Version: 0.0.1
System-Bundle: yes
Import-Package: org.osgi.framework,
org.jitsi.service.configuration,
net.java.sip.communicator.util
net.java.sip.communicator.util,
net.java.sip.communicator.util.launchutils

@ -25,41 +25,44 @@
public class SIPCommunicator
{
/**
* The name of the property that stores our home dir location.
* Legacy home directory names that we can use if current dir name is the
* currently active name (overridableDirName).
*/
public static final String PNAME_SC_HOME_DIR_LOCATION =
"net.java.sip.communicator.SC_HOME_DIR_LOCATION";
private static final String[] LEGACY_DIR_NAMES
= { ".sip-communicator", "SIP Communicator" };
/**
* The name of the property that stores our home dir name.
* Name of the possible configuration file names (used under macosx).
*/
public static final String PNAME_SC_HOME_DIR_NAME =
"net.java.sip.communicator.SC_HOME_DIR_NAME";
private static final String[] LEGACY_CONFIGURATION_FILE_NAMES
= {
"sip-communicator.properties",
"jitsi.properties",
"sip-communicator.xml",
"jitsi.xml"
};
/**
* The currently active name.
*/
private static String overridableDirName = "Jitsi";
private static final String OVERRIDABLE_DIR_NAME = "Jitsi";
/**
* Legacy home directory names that we can use if current dir name
* is the currently active name (overridableDirName).
* The name of the property that stores our home dir location.
*/
private static String[] legacyDirNames =
{".sip-communicator", "SIP Communicator"};
public static final String PNAME_SC_HOME_DIR_LOCATION
= "net.java.sip.communicator.SC_HOME_DIR_LOCATION";
/**
* Name of the possible configuration file names (used under macosx).
* The name of the property that stores our home dir name.
*/
private static String[] legacyConfigurationFileNames =
{"sip-communicator.properties", "jitsi.properties",
"sip-communicator.xml", "jitsi.xml"};
public static final String PNAME_SC_HOME_DIR_NAME
= "net.java.sip.communicator.SC_HOME_DIR_NAME";
/**
* Starts the SIP Communicator.
*
* @param args command line args if any
*
* @throws Exception whenever it makes sense.
*/
public static void main(String[] args)
@ -79,12 +82,18 @@ public static void main(String[] args)
setScHomeDir(osName);
// this needs to be set before any DNS lookup is run
File f = new File(System.getProperty(PNAME_SC_HOME_DIR_LOCATION),
System.getProperty(PNAME_SC_HOME_DIR_NAME)
+ File.separator + ".usednsjava");
File f
= new File(
System.getProperty(PNAME_SC_HOME_DIR_LOCATION),
System.getProperty(PNAME_SC_HOME_DIR_NAME)
+ File.separator
+ ".usednsjava");
if(f.exists())
{
System.setProperty(
"sun.net.spi.nameservice.provider.1", "dns,dnsjava");
"sun.net.spi.nameservice.provider.1",
"dns,dnsjava");
}
if (version.startsWith("1.4") || vmVendor.startsWith("Gnu") ||
vmVendor.startsWith("Free"))
@ -162,7 +171,7 @@ else if (osName.startsWith("Windows"))
* wrappers to call it.
*
* @param osName the name of the OS according to which the SC_HOME_DIR_*
* properties are to be set
* properties are to be set
*/
static void setScHomeDir(String osName)
{
@ -188,8 +197,8 @@ static void setScHomeDir(String osName)
// 2) if such is forced and is the overridableDirName check it
// (the later is the case with name transition SIP Communicator
// -> Jitsi, check them only for Jitsi)
boolean chekLegacyDirNames = (name == null) ||
name.equals(overridableDirName);
boolean chekLegacyDirNames
= (name == null) || name.equals(OVERRIDABLE_DIR_NAME);
if (osName.startsWith("Mac"))
{
@ -234,28 +243,25 @@ && new File(defaultLocation, defaultName).isDirectory())
name = defaultName;
}
// if we need to check legacy names and there is no
// current home dir already created
// if we need to check legacy names and there is no current home dir
// already created
if(chekLegacyDirNames
&& !checkHomeFolderExist(location, name, osName))
&& !checkHomeFolderExist(location, name, osName))
{
// now check whether some of the legacy dir names
// exists, and use it if exist
for(int i = 0; i < legacyDirNames.length; i++)
// now check whether a legacy dir name exists and use it
for(String dir : LEGACY_DIR_NAMES)
{
// check the platform specific directory
if(checkHomeFolderExist(
location, legacyDirNames[i], osName))
if(checkHomeFolderExist(location, dir, osName))
{
name = legacyDirNames[i];
name = dir;
break;
}
// now check it and in the default location
if(checkHomeFolderExist(
defaultLocation, legacyDirNames[i], osName))
if(checkHomeFolderExist(defaultLocation, dir, osName))
{
name = legacyDirNames[i];
name = dir;
location = defaultLocation;
break;
}
@ -271,13 +277,12 @@ && new File(defaultLocation, defaultName).isDirectory())
}
/**
* Checks whether home folder exists.
* Special situation checked under macosx, due to created folder
* of the new version of the updater we may end up with our
* settings in 'SIP Communicator' folder and having 'Jitsi' folder
* created by the updater(its download location).
* So we check not only the folder exist but whether it contains
* any of the known configuration files in it.
* Checks whether home folder exists. Special situation checked under
* macosx, due to created folder of the new version of the updater we may
* end up with our settings in 'SIP Communicator' folder and having 'Jitsi'
* folder created by the updater(its download location). So we check not
* only the folder exist but whether it contains any of the known
* configuration files in it.
*
* @param parent the parent folder
* @param name the folder name to check.
@ -285,17 +290,15 @@ && new File(defaultLocation, defaultName).isDirectory())
* @return whether folder exists.
*/
static boolean checkHomeFolderExist(
String parent, String name, String osName)
String parent, String name, String osName)
{
if(osName.startsWith("Mac"))
{
for(int i = 0; i < legacyConfigurationFileNames.length; i++)
for(String f : LEGACY_CONFIGURATION_FILE_NAMES)
{
if(new File(new File(parent, name)
, legacyConfigurationFileNames[i]).exists())
if(new File(new File(parent, name), f).exists())
return true;
}
return false;
}

@ -0,0 +1,67 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.util.launchutils;
import java.io.*;
import java.util.*;
/**
* In the fashion of <tt>java.io.DeleteOnExitHook</tt>, provides a way to delete
* files when <tt>Runtime.halt(int)</tt> is to be invoked.
*
* @author Lyubomir Marinov
*/
public class DeleteOnHaltHook
{
/**
* The set of files to be deleted when <tt>Runtime.halt(int)</tt> is to be
* invoked.
*/
private static Set<String> files = new LinkedHashSet<String>();
/**
* Adds a file to the set of files to be deleted when
* <tt>Runtime.halt(int)</tt> is to be invoked.
*
* @param file the name of the file to be deleted when
* <tt>Runtime.halt(int)</tt> is to be invoked
*/
public static synchronized void add(String file)
{
if (files == null)
throw new IllegalStateException("Shutdown in progress.");
else
files.add(file);
}
/**
* Deletes the files which have been registered for deletion when
* <tt>Runtime.halt(int)</tt> is to be invoked.
*/
public static void runHooks()
{
Set<String> files;
synchronized (DeleteOnHaltHook.class)
{
files = DeleteOnHaltHook.files;
DeleteOnHaltHook.files = null;
}
if (files != null)
{
List<String> toBeDeleted = new ArrayList<String>(files);
Collections.reverse(toBeDeleted);
for (String filename : toBeDeleted)
new File(filename).delete();
}
}
/** Prevents the initialization of <tt>DeleteOnHaltHook</tt> instances. */
private DeleteOnHaltHook() {}
}

@ -15,20 +15,20 @@
import net.java.sip.communicator.util.*;
/**
* This class is used to prevent from running multiple instances of Jitsi.
* The class binds a socket somewhere on the localhost domain and
* records its socket address in the Jitsi configuration directory.
* This class is used to prevent from running multiple instances of Jitsi. The
* class binds a socket somewhere on the localhost domain and records its socket
* address in the Jitsi configuration directory.
*
* All following instances of Jitsi (and hence this class) will look
* for this record in the configuration directory and try to connect to the
* original instance through the socket address in there.
* All following instances of Jitsi (and hence this class) will look for this
* record in the configuration directory and try to connect to the original
* instance through the socket address in there.
*
* @author Emil Ivov
*/
public class SipCommunicatorLock extends Thread
{
private static final Logger logger = Logger
.getLogger(SipCommunicatorLock.class);
private static final Logger logger
= Logger.getLogger(SipCommunicatorLock.class);
/**
* Indicates that something went wrong. More information will probably be
@ -44,8 +44,8 @@ public class SipCommunicatorLock extends Thread
/**
* Returned by the soft start method to indicate that an instance of Jitsi
* has been already started and we should exit. This return
* code also indicates that all arguments were passed to that new instance.
* has been already started and we should exit. This return code also
* indicates that all arguments were passed to that new instance.
*/
public static final int ALREADY_STARTED = 301;
@ -112,11 +112,11 @@ public class SipCommunicatorLock extends Thread
private static final long LOCK_FILE_READ_WAIT = 500;
/**
* An address that is reported not local on macosx and is
* assigned as default on loopback interface.
* An address that is reported not local on macosx and is assigned as
* default on loopback interface.
*/
private static final String WEIRD_MACOSX_LOOPBACK_ADDRESS =
"fe80:0:0:0:0:0:0:1";
private static final String WEIRD_MACOSX_LOOPBACK_ADDRESS
= "fe80:0:0:0:0:0:0:1";
/**
* Tries to lock the configuration directory. If lock-ing is not possible
@ -124,17 +124,14 @@ public class SipCommunicatorLock extends Thread
* list of args to that running instance.
* <p>
* There are three possible outcomes of this method. 1. We lock
* successfully; 2. We fail to lock because another instance of Jitsi
* is already running; 3. We fail to lock for some unknown
* error. Each of these cases is represented by an error code returned as a
* result.
*
* @param args
* the array of arguments that we are to submit in case an
* instance of Jitsi has already been started.
* successfully; 2. We fail to lock because another instance of Jitsi is
* already running; 3. We fail to lock for some unknown error. Each of these
* cases is represented by an error code returned as a result.
*
* @param args the array of arguments that we are to submit in case an
* instance of Jitsi has already been started.
* @return an error or success code indicating the outcome of the lock
* operation.
* operation.
*/
public int tryLock(String[] args)
{
@ -172,10 +169,8 @@ public int tryLock(String[] args)
* not return the ALREADY_RUNNING code as it is assumed that this has
* already been checked before calling this method.
*
* @param lockFile
* the file that we should use to lock the configuration
* directory.
*
* @param lockFile the file that we should use to lock the configuration
* directory.
* @return the SUCCESS or ERROR codes defined by this class.
*/
private int lock(File lockFile)
@ -215,6 +210,7 @@ private int lock(File lockFile)
}
lockFile.deleteOnExit();
DeleteOnHaltHook.add(lockFile.getAbsolutePath());
writeLockFile(lockFile, serverSocketAddress);
@ -227,7 +223,7 @@ private int lock(File lockFile)
* other instances of Jitsi that are trying to start.
*
* @return the <tt>ERROR</tt> code if something goes wrong and
* <tt>SUCCESS</tt> otherwise.
* <tt>SUCCESS</tt> otherwise.
*/
private int startLockServer(InetSocketAddress localAddress)
{
@ -268,7 +264,7 @@ private int startLockServer(InetSocketAddress localAddress)
* on.
*
* @return an InetAddress (most probably a loopback) that we can use to bind
* our semaphore socket on.
* our semaphore socket on.
*/
private InetAddress getRandomBindAddress()
{
@ -334,13 +330,12 @@ private int getRandomPortNumber()
}
/**
* Calls reading of the lock file, retrying if there is
* nothing written in it.
* Calls reading of the lock file, retrying if there is nothing written in
* it.
*
* @param lockFile the file that we are to parse.
*
* @return the <tt>SocketAddress</tt> that we should use to communicate with
* a possibly already running version of Jitsi.
* a possibly already running version of Jitsi.
*/
private InetSocketAddress readLockFileRetrying(File lockFile)
{
@ -372,11 +367,9 @@ private InetSocketAddress readLockFileRetrying(File lockFile)
* contents of <tt>lockFile</tt> and asserts presence of all properties
* mandated by this version.
*
* @param lockFile
* the file that we are to parse.
*
* @param lockFile the file that we are to parse.
* @return the <tt>SocketAddress</tt> that we should use to communicate with
* a possibly already running version of Jitsi.
* a possibly already running version of Jitsi.
*/
private InetSocketAddress readLockFile(File lockFile)
{
@ -435,29 +428,28 @@ private InetSocketAddress readLockFile(File lockFile)
* Records our <tt>lockAddress</tt> into <tt>lockFile</tt> using the
* standard properties format.
*
* @param lockFile
* the file that we should store the address in.
* @param lockAddress
* the address that we have to record.
*
* @param lockFile the file that we should store the address in.
* @param lockAddress the address that we have to record.
* @return <tt>SUCCESS</tt> upon success and <tt>ERROR</tt> if we fail to
* store the file.
* store the file.
*/
private int writeLockFile(File lockFile, InetSocketAddress lockAddress)
{
Properties lockProperties = new Properties();
lockProperties.setProperty(PNAME_LOCK_ADDRESS, lockAddress.getAddress()
.getHostAddress());
lockProperties.setProperty(PNAME_LOCK_PORT, Integer
.toString(lockAddress.getPort()));
lockProperties.setProperty(
PNAME_LOCK_ADDRESS,
lockAddress.getAddress().getHostAddress());
lockProperties.setProperty(
PNAME_LOCK_PORT,
Integer.toString(lockAddress.getPort()));
try
{
lockProperties.store(new FileOutputStream(lockFile),
"Jitsi lock file. This file will be automatically"
+ "removed when execution of Jitsi terminates.");
lockProperties.store(
new FileOutputStream(lockFile),
"Jitsi lock file. This file will be automatically removed"
+ " when execution of Jitsi terminates.");
}
catch (FileNotFoundException e)
{
@ -470,7 +462,6 @@ private int writeLockFile(File lockFile, InetSocketAddress lockAddress)
}
return SUCCESS;
}
/**
@ -482,15 +473,15 @@ private int writeLockFile(File lockFile, InetSocketAddress lockAddress)
*/
private File getLockFile()
{
String homeDirLocation = System
.getProperty(SIPCommunicator.PNAME_SC_HOME_DIR_LOCATION);
String homeDirName = System
.getProperty(SIPCommunicator.PNAME_SC_HOME_DIR_NAME);
String homeDirLocation
= System.getProperty(SIPCommunicator.PNAME_SC_HOME_DIR_LOCATION);
String homeDirName
= System.getProperty(SIPCommunicator.PNAME_SC_HOME_DIR_NAME);
String fileSeparator = System.getProperty("file.separator");
String fullLockFileName = homeDirLocation + fileSeparator + homeDirName
+ fileSeparator + LOCK_FILE_NAME;
String fullLockFileName
= homeDirLocation + fileSeparator
+ homeDirName + fileSeparator
+ LOCK_FILE_NAME;
return new File(fullLockFileName);
}
@ -500,13 +491,11 @@ private File getLockFile()
* <tt>addressStr</tt> or <tt>null</tt> if no such address exists on the
* local interfaces.
*
* @param addressStr
* the address string that we are trying to resolve into an
* <tt>InetAddress</tt>
*
* @param addressStr the address string that we are trying to resolve into
* an <tt>InetAddress</tt>
* @return an <tt>InetAddress</tt> instance corresponding to
* <tt>addressStr</tt> or <tt>null</tt> if none of the local
* interfaces has such an address.
* <tt>addressStr</tt> or <tt>null</tt> if none of the local interfaces has
* such an address.
*/
private InetAddress findLocalAddress(String addressStr)
{
@ -549,7 +538,6 @@ private InetAddress findLocalAddress(String addressStr)
*
* @param sockAddr the address that we are to connect to.
* @param args the args that we need to send to <tt>sockAddr</tt>.
*
* @return <tt>SUCCESS</tt> upond success and <tt>ERROR</tt> if anything
* goes wrong.
*/
@ -604,12 +592,12 @@ private int interInstanceConnect(InetSocketAddress sockAddr, String[] args)
/**
* We use this thread to communicate with an already running instance of
* Jitsi. This thread will listen for a reply to a message that we've
* sent to the other instance. We will wait for this message for a maximum
* of <tt>runDuration</tt> milliseconds and then consider the remote
* instance dead.
* Jitsi. This thread will listen for a reply to a message that we've sent
* to the other instance. We will wait for this message for a maximum of
* <tt>runDuration</tt> milliseconds and then consider the remote instance
* dead.
*/
private class LockClient extends Thread
private static class LockClient extends Thread
{
/**
* The <tt>String</tt> that we've read from the socketInputStream
@ -619,14 +607,13 @@ private class LockClient extends Thread
/**
* The socket that this <tt>LockClient</tt> is created to read from.
*/
private Socket interInstanceSocket = null;
private final Socket interInstanceSocket;
/**
* Creates a <tt>LockClient</tt> that should read whatever data we
* receive on <tt>sockInputStream</tt>.
*
* @param commSocket
* the socket that this client should be reading from.
* @param commSocket the socket that this client should be reading from.
*/
public LockClient(Socket commSocket)
{
@ -640,8 +627,8 @@ public LockClient(Socket commSocket)
* Blocks until a reply has been received or until run<tt>Duration</tt>
* milliseconds had passed.
*
* @param runDuration the number of seconds to wait for a reply from
* the remote instance
* @param runDuration the number of seconds to wait for a reply from the
* remote instance
*/
public void waitForReply(long runDuration)
{
@ -694,32 +681,35 @@ public void run()
// does not necessarily mean something is wrong. Could be
// that we got tired of waiting and want to quit.
if (logger.isInfoEnabled())
logger.info("An IOException is thrown while reading sock", exc);
{
logger.info(
"An IOException is thrown while reading sock",
exc);
}
}
}
}
/**
* We start this thread when running Jitsi as a means of
* notifying others that this is
* We start this thread when running Jitsi as a means of notifying others
* that this is
*/
private class LockServer extends Thread
private static class LockServer extends Thread
{
private boolean keepAccepting = true;
/**
* The socket that we use for cross instance lock and communication.
*/
private ServerSocket lockSocket = null;
private final ServerSocket lockSocket;
/**
* Creates an instance of this <tt>LockServer</tt> wrapping the
* specified <tt>serverSocket</tt>. It is expected that the serverSocket
* will be already bound and ready to accept.
*
* @param serverSocket
* the serverSocket that we should use for inter instance
* communication.
* @param serverSocket the serverSocket that we should use for inter
* instance communication.
*/
public LockServer(ServerSocket serverSocket)
{
@ -764,9 +754,8 @@ private static class LockServerConnectionProcessor extends Thread
* would handle parameters received through the
* <tt>connectionSocket</tt>.
*
* @param connectionSocket
* the socket that we will be using to read arguments from
* the remote Jitsi instance.
* @param connectionSocket the socket that we will be using to read
* arguments from the remote Jitsi instance.
*/
public LockServerConnectionProcessor(Socket connectionSocket)
{
@ -857,13 +846,12 @@ else if (line.startsWith(ARGUMENT))
/**
* Determines whether or not the <tt>iface</tt> interface is a loopback
* interface. We use this method as a replacement to the
* <tt>NetworkInterface.isLoopback()</tt> method that only comes with
* java 1.6.
* <tt>NetworkInterface.isLoopback()</tt> method that only comes with Java
* 1.6.
*
* @param iface the inteface that we'd like to determine as loopback or not.
*
* @return true if <tt>iface</tt> contains at least one loopback address
* and <tt>false</tt> otherwise.
* @return true if <tt>iface</tt> contains at least one loopback address and
* <tt>false</tt> otherwise.
*/
private boolean isLoopbackInterface(NetworkInterface iface)
{
@ -886,8 +874,8 @@ private boolean isLoopbackInterface(NetworkInterface iface)
{
InetAddress address = addresses.nextElement();
if(address.isLoopbackAddress()
|| address.getHostAddress()
.startsWith(WEIRD_MACOSX_LOOPBACK_ADDRESS))
|| address.getHostAddress().startsWith(
WEIRD_MACOSX_LOOPBACK_ADDRESS))
return true;
}

Loading…
Cancel
Save