/**
* Finds the corresponding NakReceiverWindow and adds the message to it (according to seqno). Then removes as many
* messages as possible from the NRW and passes them up the stack. Discards messages from non-members.
*/
private void handleMessage(Message msg, NakAckHeader hdr) {
NakReceiverWindow win;
Message msg_to_deliver;
Address sender=msg.getSrc();
if(sender == null) {
if(log.isErrorEnabled())
log.error("sender of message is null");
return;
}
if(trace) {
StringBuffer sb=new StringBuffer('[');
sb.append(local_addr).append(": received ").append(sender).append('#').append(hdr.seqno);
log.trace(sb.toString());
}
// msg is potentially re-sent later as result of XMIT_REQ reception; that's why hdr is added !
// Changed by bela Jan 29 2003: we currently don't resend from received msgs, just from sent_msgs !
// msg.putHeader(getName(), hdr);
synchronized(received_msgs) {
win=(NakReceiverWindow)received_msgs.get(sender);
}
if(win == null) { // discard message if there is no entry for sender
if(leaving)
return;
if(warn) {
StringBuffer sb=new StringBuffer('[');
sb.append(local_addr).append("] discarded message from non-member ")
.append(sender).append(", my view is " ).append(this.view);
log.warn(sb);
}
return;
}
win.add(hdr.seqno, msg); // add in order, then remove and pass up as many msgs as possible
// Prevents concurrent passing up of messages by different threads (http://jira.jboss.com/jira/browse/JGRP-198);
// this is all the more important once we have a threadless stack (http://jira.jboss.com/jira/browse/JGRP-181),
// where lots of threads can come up to this point concurrently, but only 1 is allowed to pass at a time
// We *can* deliver messages from *different* senders concurrently, e.g. reception of P1, Q1, P2, Q2 can result in
// delivery of P1, Q1, Q2, P2: FIFO (implemented by NAKACK) says messages need to be delivered only in the
// order in which they were sent by the sender
synchronized(win) {
while((msg_to_deliver=win.remove()) != null) {
// Changed by bela Jan 29 2003: not needed (see above)
//msg_to_deliver.removeHeader(getName());
passUp(new Event(Event.MSG, msg_to_deliver));
}