mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-08 05:24:39 +01:00
ensure writer gets run every time OS schedules via onHandleWork()
This commit is contained in:
parent
bf2ab49c20
commit
ab0469fe39
1 changed files with 72 additions and 42 deletions
|
@ -389,6 +389,13 @@ public class RelayService extends JobIntentService
|
|||
DbgUtils.assertOnUIThread( false );
|
||||
Log.d( TAG, "%s.onHandleWork(cmd=%s)", this, cmdFrom( intent ) );
|
||||
handleCommand( intent );
|
||||
|
||||
boolean goOn = mThreads.serviceQueue();
|
||||
if ( !goOn ) {
|
||||
Log.e( TAG, "onHandleWork(): need to exit... HELP!!!!" );
|
||||
mThreads.killThreads();
|
||||
}
|
||||
|
||||
resetExitTimer();
|
||||
Log.d( TAG, "%s.onHandleWork(cmd=%s) DONE", this, cmdFrom( intent ) );
|
||||
}
|
||||
|
@ -405,6 +412,8 @@ public class RelayService extends JobIntentService
|
|||
}
|
||||
|
||||
if ( startImmediately ) {
|
||||
// Log.d( TAG, "onDestroy(): restarting: %d in queue",
|
||||
// mThreads.m_queue.size() );
|
||||
timerFired( this );
|
||||
} else if ( shouldMaintainConnection() ) {
|
||||
long interval_millis = getMaxIntervalSeconds() * 1000;
|
||||
|
@ -1068,9 +1077,12 @@ public class RelayService extends JobIntentService
|
|||
// continue to use the instance for a short while after returning.
|
||||
void unsetService()
|
||||
{
|
||||
// RelayService oldService;
|
||||
synchronized ( mServiceHolder ) {
|
||||
// oldService = mServiceHolder[0];
|
||||
mServiceHolder[0] = null;
|
||||
}
|
||||
// Log.d( TAG, "unsetService() DONE (was %s)", oldService );
|
||||
}
|
||||
|
||||
private RelayService getService() throws InterruptedException
|
||||
|
@ -1163,6 +1175,49 @@ public class RelayService extends JobIntentService
|
|||
}
|
||||
}
|
||||
|
||||
// Break out the work of sending queued packets so it can be called
|
||||
// from several threads. Fixes starvation problems on some devices.
|
||||
private synchronized boolean serviceQueue()
|
||||
{
|
||||
Log.d( TAG, "serviceQueue()" );
|
||||
boolean shouldGoOn = true;
|
||||
List<PacketData> dataListUDP = new ArrayList<>();
|
||||
List<PacketData> dataListWeb = new ArrayList<>();
|
||||
PacketData outData;
|
||||
try {
|
||||
long ts = s_packetsSentUDP.size() > 0 ? 10 : 1000;
|
||||
Log.d( TAG, "blocking %dms on poll()", ts );
|
||||
for ( outData = m_queue.poll( ts, TimeUnit.MILLISECONDS );
|
||||
null != outData;
|
||||
outData = m_queue.poll() ) { // doesn't block
|
||||
Log.d( TAG, "removed packet from queue (%d left): %s",
|
||||
m_queue.size(), outData );
|
||||
if ( outData == sEOQPacket ) {
|
||||
shouldGoOn = false;
|
||||
break;
|
||||
} else if ( skipNativeSend() || outData.getForWeb() ) {
|
||||
dataListWeb.add( outData );
|
||||
} else {
|
||||
dataListUDP.add( outData );
|
||||
}
|
||||
}
|
||||
|
||||
sendViaWeb( dataListWeb );
|
||||
sendViaUDP( dataListUDP );
|
||||
|
||||
getService().resetExitTimer();
|
||||
|
||||
runUDPAckTimer();
|
||||
|
||||
ConnStatusHandler.showSuccessOut();
|
||||
} catch ( InterruptedException ie ) {
|
||||
Log.w( TAG, "write thread killed" );
|
||||
shouldGoOn = false;
|
||||
}
|
||||
Log.d( TAG, "serviceQueue() => %b", shouldGoOn );
|
||||
return shouldGoOn;
|
||||
}
|
||||
|
||||
private void startWriteThread()
|
||||
{
|
||||
Assert.assertNull( m_UDPWriteThread );
|
||||
|
@ -1170,59 +1225,34 @@ public class RelayService extends JobIntentService
|
|||
m_UDPWriteThread = new Thread( null, new Runnable() {
|
||||
public void run() {
|
||||
Log.i( TAG, "write thread starting" );
|
||||
for ( boolean gotEOQ = false; !gotEOQ; ) {
|
||||
List<PacketData> dataListUDP = new ArrayList<>();
|
||||
List<PacketData> dataListWeb = new ArrayList<>();
|
||||
PacketData outData;
|
||||
try {
|
||||
long ts = s_packetsSentUDP.size() > 0 ? 10 : 3600;
|
||||
Log.d( TAG, "blocking %d sec on poll()", ts );
|
||||
for ( outData = m_queue.poll(ts, TimeUnit.SECONDS);
|
||||
null != outData;
|
||||
outData = m_queue.poll() ) { // doesn't block
|
||||
Log.d( TAG, "removed packet from queue: %s", outData );
|
||||
if ( outData == sEOQPacket ) {
|
||||
gotEOQ = true;
|
||||
break;
|
||||
} else if ( skipNativeSend() || outData.getForWeb() ) {
|
||||
dataListWeb.add( outData );
|
||||
} else {
|
||||
dataListUDP.add( outData );
|
||||
}
|
||||
}
|
||||
|
||||
sendViaWeb( dataListWeb );
|
||||
sendViaUDP( dataListUDP );
|
||||
|
||||
getService().resetExitTimer();
|
||||
|
||||
runUDPAckTimer();
|
||||
|
||||
ConnStatusHandler.showSuccessOut();
|
||||
} catch ( InterruptedException ie ) {
|
||||
Log.w( TAG, "write thread killed" );
|
||||
for ( ; ; ) {
|
||||
if ( !serviceQueue() ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Log.i( TAG, "write thread killing read thread" );
|
||||
|
||||
killThreads();
|
||||
// now kill the read thread
|
||||
m_UDPSocket.close();
|
||||
try {
|
||||
m_UDPReadThread.join();
|
||||
} catch( java.lang.InterruptedException ie ) {
|
||||
Log.ex( TAG, ie );
|
||||
}
|
||||
|
||||
m_UDPSocket = null;
|
||||
Log.i( TAG, "write thread exiting (with %d in queue)",
|
||||
m_queue.size() );
|
||||
}
|
||||
}, getClass().getName() );
|
||||
m_UDPWriteThread.start();
|
||||
}
|
||||
|
||||
private void killThreads()
|
||||
{
|
||||
m_UDPSocket.close();
|
||||
try {
|
||||
m_UDPReadThread.join();
|
||||
} catch( java.lang.InterruptedException ie ) {
|
||||
Log.ex( TAG, ie );
|
||||
}
|
||||
|
||||
m_UDPSocket = null;
|
||||
Log.i( TAG, "write thread exiting (with %d in queue)",
|
||||
m_queue.size() );
|
||||
}
|
||||
|
||||
private int sendViaWeb( List<PacketData> packets ) throws InterruptedException
|
||||
{
|
||||
int sentLen = 0;
|
||||
|
|
Loading…
Reference in a new issue