* Takes the argument highest_seqnos and compares it to the current digest. If the current digest has fewer messages,
* then send retransmit messages for the missing messages. Return when all missing messages have been received. If
* we're waiting for a missing message from P, and P crashes while waiting, we need to exclude P from the wait set.
*/
private void rebroadcastMessages() {
Digest my_digest;
Map<Address,Digest.Entry> their_digest;
Address sender;
Digest.Entry their_entry, my_entry;
long their_high, my_high;
long sleep=max_rebroadcast_timeout / NUM_REBROADCAST_MSGS;
long wait_time=max_rebroadcast_timeout, start=System.currentTimeMillis();
while(wait_time > 0) {
rebroadcast_digest_lock.lock();
try {
if(rebroadcast_digest == null)
break;
their_digest=rebroadcast_digest.getSenders();
}
finally {
rebroadcast_digest_lock.unlock();
}
my_digest=getDigest();
boolean xmitted=false;
for(Map.Entry<Address,Digest.Entry> entry: their_digest.entrySet()) {
sender=entry.getKey();
their_entry=entry.getValue();
my_entry=my_digest.get(sender);
if(my_entry == null)
continue;
their_high=their_entry.getHighest();
// Cannot ask for 0 to be retransmitted because the first seqno in NAKACK and UNICAST(2) is always 1 !
// Also, we need to ask for retransmission of my_high+1, because we already *have* my_high, and don't
// need it, so the retransmission range is [my_high+1 .. their_high]: *exclude* my_high, but *include*
// their_high
my_high=Math.max(1, my_entry.getHighest() +1);
if(their_high > my_high) {
if(log.isTraceEnabled())
log.trace("[" + local_addr + "] fetching " + my_high + "-" + their_high + " from " + sender);
retransmit(my_high, their_high, sender, true); // use multicast to send retransmit request
xmitted=true;
}
}
if(!xmitted)
return; // we're done; no retransmissions are needed anymore. our digest is >= rebroadcast_digest
rebroadcast_lock.lock();
try {
try {
my_digest=getDigest();
rebroadcast_digest_lock.lock();
try {
if(!rebroadcasting || my_digest.isGreaterThanOrEqual(rebroadcast_digest))
return;
}
finally {
rebroadcast_digest_lock.unlock();
}