I am not sure about that. The selector.wakeup()
call in schedule()
should make the select()
call in the reactor thread return immediately (see the javadoc of Selector.wakeup()
).
This is only true if the Selector is in the blocking selection operation wait state i.e. after the execution of
newSelectedKeysCount = selector.select(selectWait);
In this special case where Selector is not in the blocking selection operation wait state nor it in the Selector synchronized mode, the selector.waitup() in the schedule method is immediately consumed but does nothing to to the existing running thread; and the Selector will wait until the old selectWait is timeout.
If you review my previous debug log on the pings, you can see that the ping is not being executed at 20Sec regular interval, but skipped at times when the above race condition happen.
I move the the synchronized() before the next scheduledActions.peek(); i.e.
synchronized (selector) {
ScheduledAction nextScheduledAction = scheduledActions.peek();
long selectWait;
if (nextScheduledAction == null) {
// There is no next scheduled action, wait indefinitely in select().
selectWait = 0;
} else {
selectWait = nextScheduledAction.getTimeToDueMillis();
}
By doing that, selector.waitup() in schedule method will be put on hold until Selector has entered blocking selection operation and the thread exited the synchronized() loop; only then the on hold selector.waitup() gets executed, and selectWait gets re-init with the correct value.
I have verified the new patch, the ping is being executed at 20S interval without missing a single one.
as captured below with my proposed patch.
2019-06-04 17:10:14.962 11557-1442/org.atalk.android D/SMACK: SENT (2):
<iq to='atalk.org' id='vJLSF-512' type='get'>
<ping xmlns='urn:xmpp:ping'/>
</iq>
2019-06-04 17:10:14.983 11557-1443/org.atalk.android D/SMACK: RECV (2):
<iq xml:lang='en' to='swordfish@atalk.org/atalk' from='atalk.org' type='result' id='vJLSF-512'/>
2019-06-04 17:10:14.989 11557-1443/org.atalk.android D/SMACK: RECV (2):
<r xmlns='urn:xmpp:sm:3'/>
2019-06-04 17:10:14.994 11557-1442/org.atalk.android D/SMACK: SENT (2):
<a xmlns='urn:xmpp:sm:3' h='25'/>
2019-06-04 17:10:35.023 11557-1442/org.atalk.android D/SMACK: SENT (2):
<iq to='atalk.org' id='vJLSF-514' type='get'>
<ping xmlns='urn:xmpp:ping'/>
</iq>
2019-06-04 17:10:35.045 11557-1443/org.atalk.android D/SMACK: RECV (2):
<iq xml:lang='en' to='swordfish@atalk.org/atalk' from='atalk.org' type='result' id='vJLSF-514'/>
2019-06-04 17:10:35.058 11557-1443/org.atalk.android D/SMACK: RECV (2):
<r xmlns='urn:xmpp:sm:3'/>
2019-06-04 17:10:35.062 11557-1442/org.atalk.android D/SMACK: SENT (2):
<a xmlns='urn:xmpp:sm:3' h='26'/>
2019-06-04 17:10:55.090 11557-1442/org.atalk.android D/SMACK: SENT (2):
<iq to='atalk.org' id='vJLSF-516' type='get'>
<ping xmlns='urn:xmpp:ping'/>
</iq>
2019-06-04 17:10:55.108 11557-1443/org.atalk.android D/SMACK: RECV (2):
<iq xml:lang='en' to='swordfish@atalk.org/atalk' from='atalk.org' type='result' id='vJLSF-516'/>
2019-06-04 17:10:55.116 11557-1443/org.atalk.android D/SMACK: RECV (2):
<r xmlns='urn:xmpp:sm:3'/>
2019-06-04 17:10:55.122 11557-1442/org.atalk.android D/SMACK: SENT (2):
<a xmlns='urn:xmpp:sm:3' h='27'/>
2019-06-04 17:11:15.151 11557-1442/org.atalk.android D/SMACK: SENT (2):
<iq to='atalk.org' id='vJLSF-518' type='get'>
<ping xmlns='urn:xmpp:ping'/>
</iq>
2019-06-04 17:11:15.157 11557-1442/org.atalk.android D/SMACK: SENT (2):
<r xmlns='urn:xmpp:sm:3'/>
2019-06-04 17:11:15.169 11557-1443/org.atalk.android D/SMACK: RECV (2):
<iq xml:lang='en' to='swordfish@atalk.org/atalk' from='atalk.org' type='result' id='vJLSF-518'/>
2019-06-04 17:11:15.178 11557-1443/org.atalk.android D/SMACK: RECV (2):
<r xmlns='urn:xmpp:sm:3'/>
2019-06-04 17:11:15.181 11557-1442/org.atalk.android D/SMACK: SENT (2):
<a xmlns='urn:xmpp:sm:3' h='28'/>
2019-06-04 17:11:15.186 11557-1443/org.atalk.android D/SMACK: RECV (2):
<a h='20' xmlns='urn:xmpp:sm:3'/>
2019-06-04 17:11:35.215 11557-1442/org.atalk.android D/SMACK: SENT (2):
<iq to='atalk.org' id='vJLSF-520' type='get'>
<ping xmlns='urn:xmpp:ping'/>
</iq>
2019-06-04 17:11:35.229 11557-1443/org.atalk.android D/SMACK: RECV (2):
<iq xml:lang='en' to='swordfish@atalk.org/atalk' from='atalk.org' type='result' id='vJLSF-520'/>
2019-06-04 17:11:35.241 11557-1443/org.atalk.android D/SMACK: RECV (2):
<r xmlns='urn:xmpp:sm:3'/>
2019-06-04 17:11:35.243 11557-1442/org.atalk.android D/SMACK: SENT (2):
<a xmlns='urn:xmpp:sm:3' h='29'/>
2019-06-04 17:11:55.274 11557-1442/org.atalk.android D/SMACK: SENT (2):
<iq to='atalk.org' id='vJLSF-522' type='get'>
<ping xmlns='urn:xmpp:ping'/>
</iq>
2019-06-04 17:11:55.300 11557-1443/org.atalk.android D/SMACK: RECV (2):
<iq xml:lang='en' to='swordfish@atalk.org/atalk' from='atalk.org' type='result' id='vJLSF-522'/>
2019-06-04 17:11:55.312 11557-1443/org.atalk.android D/SMACK: RECV (2):
<r xmlns='urn:xmpp:sm:3'/>
2019-06-04 17:11:55.319 11557-1442/org.atalk.android D/SMACK: SENT (2):
<a xmlns='urn:xmpp:sm:3' h='30'/>
2019-06-04 17:12:15.331 11557-1442/org.atalk.android D/SMACK: SENT (2):
<iq to='atalk.org' id='vJLSF-524' type='get'>
<ping xmlns='urn:xmpp:ping'/>
</iq>
2019-06-04 17:12:15.350 11557-1443/org.atalk.android D/SMACK: RECV (2):
<iq xml:lang='en' to='swordfish@atalk.org/atalk' from='atalk.org' type='result' id='vJLSF-524'/>
2019-06-04 17:12:15.357 11557-1443/org.atalk.android D/SMACK: RECV (2):
<r xmlns='urn:xmpp:sm:3'/>
2019-06-04 17:12:15.360 11557-1442/org.atalk.android D/SMACK: SENT (2):
<a xmlns='urn:xmpp:sm:3' h='31'/>
If I revert my proposed patch, below is the new captured log under the same test conditions. The third ping get sent only after a delay of 99 seconds instead of 20s.
2019-06-04 17:16:43.723 2279-3146/org.atalk.android D/SMACK: SENT (0):
<iq to='atalk.org' id='OkwOr-104' type='get'>
<ping xmlns='urn:xmpp:ping'/>
</iq>
2019-06-04 17:16:43.740 2279-3147/org.atalk.android D/SMACK: RECV (0):
<iq xml:lang='en' to='swordfish@atalk.org/atalk' from='atalk.org' type='result' id='OkwOr-104'/>
2019-06-04 17:16:43.754 2279-3147/org.atalk.android D/SMACK: RECV (0):
<r xmlns='urn:xmpp:sm:3'/>
2019-06-04 17:16:43.759 2279-3146/org.atalk.android D/SMACK: SENT (0):
<a xmlns='urn:xmpp:sm:3' h='25'/>
2019-06-04 17:17:04.030 2279-3146/org.atalk.android D/SMACK: SENT (0):
<iq to='atalk.org' id='OkwOr-106' type='get'>
<ping xmlns='urn:xmpp:ping'/>
</iq>
2019-06-04 17:17:04.052 2279-3147/org.atalk.android D/SMACK: RECV (0):
<iq xml:lang='en' to='swordfish@atalk.org/atalk' from='atalk.org' type='result' id='OkwOr-106'/>
2019-06-04 17:17:04.075 2279-3147/org.atalk.android D/SMACK: RECV (0):
<r xmlns='urn:xmpp:sm:3'/>
2019-06-04 17:17:04.082 2279-3146/org.atalk.android D/SMACK: SENT (0):
<a xmlns='urn:xmpp:sm:3' h='26'/>
2019-06-04 17:18:43.882 2279-3146/org.atalk.android D/SMACK: SENT (0):
<iq to='atalk.org' id='OkwOr-108' type='get'>
<ping xmlns='urn:xmpp:ping'/>
</iq>
2019-06-04 17:18:43.902 2279-3147/org.atalk.android D/SMACK: RECV (0):
<iq xml:lang='en' to='swordfish@atalk.org/atalk' from='atalk.org' type='result' id='OkwOr-108'/>
2019-06-04 17:18:43.920 2279-3147/org.atalk.android D/SMACK: RECV (0):
<r xmlns='urn:xmpp:sm:3'/>
2019-06-04 17:18:43.924 2279-3146/org.atalk.android D/SMACK: SENT (0):
<a xmlns='urn:xmpp:sm:3' h='27'/>
2019-06-04 17:19:03.981 2279-3146/org.atalk.android D/SMACK: SENT (0):
<iq to='atalk.org' id='OkwOr-110' type='get'>
<ping xmlns='urn:xmpp:ping'/>
</iq>
<r xmlns='urn:xmpp:sm:3'/>
2019-06-04 17:19:03.994 2279-3147/org.atalk.android D/SMACK: RECV (0):
<a h='20' xmlns='urn:xmpp:sm:3'/>
2019-06-04 17:19:04.001 2279-3147/org.atalk.android D/SMACK: RECV (0):
<iq xml:lang='en' to='swordfish@atalk.org/atalk' from='atalk.org' type='result' id='OkwOr-110'/>
2019-06-04 17:19:04.017 2279-3147/org.atalk.android D/SMACK: RECV (0):
<r xmlns='urn:xmpp:sm:3'/>
2019-06-04 17:19:04.023 2279-3146/org.atalk.android D/SMACK: SENT (0):
<a xmlns='urn:xmpp:sm:3' h='28'/>
2019-06-04 17:19:24.093 2279-3146/org.atalk.android D/SMACK: SENT (0):
<iq to='atalk.org' id='OkwOr-112' type='get'>
<ping xmlns='urn:xmpp:ping'/>
</iq>
2019-06-04 17:19:24.106 2279-3147/org.atalk.android D/SMACK: RECV (0):
<iq xml:lang='en' to='swordfish@atalk.org/atalk' from='atalk.org' type='result' id='OkwOr-112'/>
2019-06-04 17:19:24.123 2279-3147/org.atalk.android D/SMACK: RECV (0):
<r xmlns='urn:xmpp:sm:3'/>
2019-06-04 17:19:24.129 2279-3146/org.atalk.android D/SMACK: SENT (0):
<a xmlns='urn:xmpp:sm:3' h='29'/>
2019-06-04 17:20:44.003 2279-3146/org.atalk.android D/SMACK: SENT (0):
<iq to='atalk.org' id='OkwOr-114' type='get'>
<ping xmlns='urn:xmpp:ping'/>
</iq>
2019-06-04 17:20:44.024 2279-3147/org.atalk.android D/SMACK: RECV (0):
<iq xml:lang='en' to='swordfish@atalk.org/atalk' from='atalk.org' type='result' id='OkwOr-114'/>
2019-06-04 17:20:44.042 2279-3147/org.atalk.android D/SMACK: RECV (0):
<r xmlns='urn:xmpp:sm:3'/>
2019-06-04 17:20:44.048 2279-3146/org.atalk.android D/SMACK: SENT (0):
<a xmlns='urn:xmpp:sm:3' h='30'/>: