mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-07 05:24:46 +01:00
get another DatagramSocket when ours goes bad
Fix longstanding bug triggered by something as simple as putting device into and out of airplane mode. Once the class-variable socket was created it was never replaced. Now respond to exceptions that mean it's useless and set it to null so existing logic will recreate it.
This commit is contained in:
parent
4354cbdc4f
commit
36cc181a5e
1 changed files with 69 additions and 45 deletions
|
@ -521,33 +521,40 @@ public class RelayService extends XWJIService
|
|||
}
|
||||
}
|
||||
|
||||
private synchronized void connectSocketOnce() throws InterruptedException
|
||||
private DatagramSocket connectSocketOnce() throws InterruptedException
|
||||
{
|
||||
if ( null == s_UDPSocket ) {
|
||||
final RelayService service = this;
|
||||
int port = XWPrefs.getDefaultRelayPort( service );
|
||||
String host = XWPrefs.getDefaultRelayHost( service );
|
||||
|
||||
try {
|
||||
s_UDPSocket = new DatagramSocket();
|
||||
s_UDPSocket.setSoTimeout(30 * 1000); // timeout so we can log
|
||||
|
||||
InetAddress addr = InetAddress.getByName( host );
|
||||
s_UDPSocket.connect( addr, port ); // remember this address
|
||||
Log.d( TAG, "connectSocket(%s:%d): s_UDPSocket now %H",
|
||||
host, port, s_UDPSocket );
|
||||
} catch( SocketException se ) {
|
||||
Log.ex( TAG, se );
|
||||
Assert.fail();
|
||||
} catch( java.net.UnknownHostException uhe ) {
|
||||
Log.ex( TAG, uhe );
|
||||
Log.e( TAG, "connectSocketOnce(): %s", uhe.getMessage() );
|
||||
// Assert.assertFalse( BuildConfig.DEBUG );
|
||||
DatagramSocket result = null;
|
||||
synchronized ( RelayService.class ) {
|
||||
if ( null != s_UDPSocket && ! s_UDPSocket.isConnected() ) {
|
||||
closeUDPSocket( s_UDPSocket );
|
||||
}
|
||||
} else if( ! s_UDPSocket.isConnected() ) {
|
||||
Log.e( TAG, "connectSocketOnce(): udp socket not connected" );
|
||||
// Assert.assertTrue( s_UDPSocket.isConnected() );
|
||||
|
||||
if ( null == s_UDPSocket ) {
|
||||
final RelayService service = this;
|
||||
int port = XWPrefs.getDefaultRelayPort( service );
|
||||
String host = XWPrefs.getDefaultRelayHost( service );
|
||||
|
||||
try {
|
||||
DatagramSocket udpSocket = new DatagramSocket();
|
||||
udpSocket.setSoTimeout(30 * 1000); // timeout so we can log
|
||||
|
||||
InetAddress addr = InetAddress.getByName( host );
|
||||
udpSocket.connect( addr, port ); // remember this address
|
||||
Log.d( TAG, "connectSocket(%s:%d): udpSocket now %H",
|
||||
host, port, udpSocket );
|
||||
s_UDPSocket = udpSocket;
|
||||
} catch( SocketException se ) {
|
||||
Log.ex( TAG, se );
|
||||
Assert.fail();
|
||||
} catch( java.net.UnknownHostException uhe ) {
|
||||
Log.ex( TAG, uhe );
|
||||
Log.e( TAG, "connectSocketOnce(): %s", uhe.getMessage() );
|
||||
// Assert.assertFalse( BuildConfig.DEBUG );
|
||||
}
|
||||
}
|
||||
result = s_UDPSocket;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean serviceQueue()
|
||||
|
@ -695,40 +702,40 @@ public class RelayService extends XWJIService
|
|||
{
|
||||
int sentLen = 0;
|
||||
|
||||
if ( packets.size() > 0 ) {
|
||||
DatagramSocket udpSocket = s_UDPSocket;
|
||||
if ( null != udpSocket && packets.size() > 0 ) {
|
||||
// Log.d( TAG, "sendViaUDP(): sending %d at once", packets.size() );
|
||||
final RelayService service = this;
|
||||
service.noteSent( packets, true );
|
||||
for ( PacketData packet : packets ) {
|
||||
boolean getOut = true;
|
||||
boolean breakNow = true;
|
||||
byte[] data = packet.assemble();
|
||||
try {
|
||||
DatagramPacket udpPacket = new DatagramPacket( data, data.length );
|
||||
s_UDPSocket.send( udpPacket );
|
||||
udpSocket.send( udpPacket );
|
||||
|
||||
sentLen += udpPacket.getLength();
|
||||
// Why's this commented out?
|
||||
// packet.setSentMS( nowMS );
|
||||
getOut = false;
|
||||
} catch ( java.net.SocketException se ) {
|
||||
Log.ex( TAG, se );
|
||||
breakNow = false;
|
||||
} catch ( IOException ex ) {
|
||||
Log.e( TAG, "fail sending to %s", udpSocket );
|
||||
Log.ex( TAG, ex );
|
||||
Log.i( TAG, "Restarting threads to force new socket" );
|
||||
ConnStatusHandler.updateStatusOut( service, null,
|
||||
CommsConnType.COMMS_CONN_RELAY,
|
||||
true );
|
||||
closeUDPSocket( udpSocket );
|
||||
|
||||
service.m_handler.post( new Runnable() {
|
||||
public void run() {
|
||||
service.stopUDPReadThread();
|
||||
}
|
||||
} );
|
||||
break;
|
||||
} catch ( java.io.IOException ioe ) {
|
||||
Log.e( TAG, "sendViaUDP(): failure \"%s\" sending on %s",
|
||||
s_UDPSocket, ioe.getMessage() );
|
||||
} catch ( NullPointerException npe ) {
|
||||
Log.w( TAG, "network problem; dropping packet" );
|
||||
}
|
||||
if ( getOut ) {
|
||||
if ( breakNow ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -736,8 +743,8 @@ public class RelayService extends XWJIService
|
|||
ConnStatusHandler.updateStatus( service, null,
|
||||
CommsConnType.COMMS_CONN_RELAY,
|
||||
sentLen > 0 );
|
||||
Log.d( TAG, "sendViaUDP(): sent %d bytes (%d packets)",
|
||||
sentLen, packets.size() );
|
||||
Log.d( TAG, "%s.sendViaUDP(): sent %d bytes (%d packets)",
|
||||
this, sentLen, packets.size() );
|
||||
}
|
||||
|
||||
return sentLen;
|
||||
|
@ -1253,6 +1260,8 @@ public class RelayService extends XWJIService
|
|||
private static class UDPReadThread extends Thread {
|
||||
private RelayService[] mServiceHolder = {null};
|
||||
|
||||
UDPReadThread() { super("UDPReadThread"); }
|
||||
|
||||
void setService( RelayService service )
|
||||
{
|
||||
Assert.assertNotNull( service );
|
||||
|
@ -1294,19 +1303,24 @@ public class RelayService extends XWJIService
|
|||
|
||||
@Override
|
||||
public void run() {
|
||||
Log.i( TAG, "%s.run() starting", this );
|
||||
Context context = XWApp.getContext();
|
||||
try {
|
||||
if ( null == s_UDPSocket ) {
|
||||
getService().connectSocketOnce(); // block until this is done
|
||||
DatagramSocket udpSocket = s_UDPSocket;
|
||||
if ( null == udpSocket ) {
|
||||
udpSocket = getService().connectSocketOnce(); // block until this is done
|
||||
}
|
||||
|
||||
Log.i( TAG, "%s.run() starting", this );
|
||||
byte[] buf = new byte[1024];
|
||||
DatagramPacket packet =
|
||||
new DatagramPacket( buf, buf.length );
|
||||
for ( ; ; ) {
|
||||
DatagramPacket packet =
|
||||
new DatagramPacket( buf, buf.length );
|
||||
if ( interrupted() ) {
|
||||
Log.d( TAG, "%s.run() interrupted; outta here", this );
|
||||
break;
|
||||
}
|
||||
try {
|
||||
s_UDPSocket.receive( packet );
|
||||
udpSocket.receive( packet );
|
||||
postGotPacket( context, packet );
|
||||
// final RelayService service = getService();
|
||||
// service.resetExitTimer();
|
||||
|
@ -1315,8 +1329,8 @@ public class RelayService extends XWJIService
|
|||
// poll timing out, typically
|
||||
// Log.d( TAG, "iioe from receive(): %s", iioe.getMessage() );
|
||||
} catch( IOException ioe ) {
|
||||
Log.d( TAG, "ioe from receive(): %s/%s", ioe.getMessage() );
|
||||
Assert.assertFalse( BuildConfig.DEBUG );
|
||||
Log.d( TAG, "ioe from receive(): %s", ioe.getMessage() );
|
||||
closeUDPSocket( udpSocket );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1340,6 +1354,16 @@ public class RelayService extends XWJIService
|
|||
}
|
||||
}
|
||||
|
||||
private static void closeUDPSocket( DatagramSocket udpSocket )
|
||||
{
|
||||
synchronized ( RelayService.class ) {
|
||||
if ( udpSocket == s_UDPSocket ) {
|
||||
s_UDPSocket.close();
|
||||
s_UDPSocket = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class AsyncSender extends Thread {
|
||||
private Context m_context;
|
||||
private HashMap<String,ArrayList<byte[]>> m_msgHash;
|
||||
|
|
Loading…
Reference in a new issue