//
continue;
}
READ_RESULT: for (;;) {
final AckNackResult anr = pckIn.readACK(ackId);
switch (anr) {
case NAK:
// More have lines are necessary to compute the
// pack on the remote side. Keep doing that.
//
resultsPending--;
break READ_RESULT;
case ACK:
// The remote side is happy and knows exactly what
// to send us. There is no further negotiation and
// we can break out immediately.
//
multiAck = MultiAck.OFF;
resultsPending = 0;
receivedAck = true;
if (statelessRPC)
state.writeTo(out, null);
break SEND_HAVES;
case ACK_CONTINUE:
case ACK_COMMON:
case ACK_READY:
// The server knows this commit (ackId). We don't
// need to send any further along its ancestry, but
// we need to continue to talk about other parts of
// our local history.
//
markCommon(walk.parseAny(ackId), anr);
receivedAck = true;
receivedContinue = true;
havesSinceLastContinue = 0;
if (anr == AckNackResult.ACK_READY)
receivedReady = true;
break;
}
if (monitor.isCancelled())
throw new CancelledException();
}
if (noDone & receivedReady)
break SEND_HAVES;
if (statelessRPC)
state.writeTo(out, null);
if (receivedContinue && havesSinceLastContinue > MAX_HAVES) {
// Our history must be really different from the remote's.
// We just sent a whole slew of have lines, and it did not
// recognize any of them. Avoid sending our entire history
// to them by giving up early.
//
break SEND_HAVES;
}
}
// Tell the remote side we have run out of things to talk about.
//
if (monitor.isCancelled())
throw new CancelledException();
if (!receivedReady || !noDone) {
// When statelessRPC is true we should always leave SEND_HAVES
// loop above while in the middle of a request. This allows us
// to just write done immediately.
//
pckOut.writeString("done\n"); //$NON-NLS-1$
pckOut.flush();
}
if (!receivedAck) {
// Apparently if we have never received an ACK earlier
// there is one more result expected from the done we
// just sent to the remote.
//
multiAck = MultiAck.OFF;
resultsPending++;
}
READ_RESULT: while (resultsPending > 0 || multiAck != MultiAck.OFF) {
final AckNackResult anr = pckIn.readACK(ackId);
resultsPending--;
switch (anr) {
case NAK:
// A NAK is a response to an end we queued earlier
// we eat it and look for another ACK/NAK message.