protected void ReduceHandler(object ro, EventArgs args) {
Pair<object, bool> retval;
Channel reduce_chan = (Channel)ro;
RpcResult value_reduced = (RpcResult)reduce_chan.State;
try {
object r_o = reduce_chan.Dequeue();
Exception r_x = r_o as Exception;
if( r_x != null ) {
if (LogEnabled) {
ProtocolLog.Write(ProtocolLog.MapReduce,
String.Format("MapReduce: {0}, resulted in: {1}.",
_node.Address, r_x));
}
SendResult(r_x);
return;
}
retval = (Pair<object, bool>)r_o;
}
catch(Exception x) {
if (LogEnabled) {
ProtocolLog.Write(ProtocolLog.MapReduce,
String.Format("MapReduce: {0}, resulted in: {1}.", _node.Address, x));
}
SendResult(x);
return;
}
//The usual transactional bit:
State state = _state;
State old_state;
State new_state;
do {
old_state = state;
/*
* compute new_state here
*/
new_state = old_state.UpdateReduce(retval, value_reduced.ResultSender != null);
state = Interlocked.CompareExchange<State>(ref _state, new_state, old_state);
}
while( state != old_state);
TryNextReduce(new_state, old_state, old_state.Pending.Head, true);
}