struct clock *);
static void rxi_Resend(struct rxevent *event, void *arg0, void *arg1,
int istack);
+static void rxi_SendDelayedAck(struct rxevent *event, void *call,
+ void *dummy);
#ifdef RX_ENABLE_LOCKS
static void rxi_SetAcksInTransmitQueue(struct rx_call *call);
rxi_busyChannelError = error;
}
+/**
+ * Set a delayed ack event on the specified call for the given time
+ *
+ * @param[in] call - the call on which to set the event
+ * @param[in] offset - the delay from now after which the event fires
+ */
+void
+rxi_PostDelayedAckEvent(struct rx_call *call, struct clock *offset)
+{
+ struct clock now, when;
+
+ clock_GetTime(&now);
+ when = now;
+ clock_Add(&when, offset);
+
+ if (!call->delayedAckEvent
+ || clock_Gt(&call->delayedAckEvent->eventTime, &when)) {
+
+ rxevent_Cancel(call->delayedAckEvent, call,
+ RX_CALL_REFCOUNT_DELAY);
+ MUTEX_ENTER(&rx_refcnt_mutex);
+ CALL_HOLD(call, RX_CALL_REFCOUNT_DELAY);
+ MUTEX_EXIT(&rx_refcnt_mutex);
+
+ call->delayedAckEvent = rxevent_PostNow(&when, &now,
+ rxi_SendDelayedAck,
+ call, 0);
+ }
+}
+
+
+
/* called with unincremented nRequestsRunning to see if it is OK to start
* a new thread in this service. Could be "no" for two reasons: over the
* max quota, or would prevent others from reaching their min quota.
afs_uint32 serial=0, flags=0;
int isFirst;
struct rx_packet *tnp;
- struct clock when, now;
if (rx_stats_active)
rx_atomic_inc(&rx_stats.dataPacketsRead);
/* We used to clear the receive queue here, in an attempt to free
* packets. However this is unsafe if the queue has received a
* soft ACK for the final packet */
- clock_GetTime(&now);
- when = now;
- clock_Add(&when, &rx_softAckDelay);
- if (!call->delayedAckEvent
- || clock_Gt(&call->delayedAckEvent->eventTime, &when)) {
- rxevent_Cancel(call->delayedAckEvent, call,
- RX_CALL_REFCOUNT_DELAY);
- MUTEX_ENTER(&rx_refcnt_mutex);
- CALL_HOLD(call, RX_CALL_REFCOUNT_DELAY);
- MUTEX_EXIT(&rx_refcnt_mutex);
+ rxi_PostDelayedAckEvent(call, &rx_softAckDelay);
- call->delayedAckEvent =
- rxevent_PostNow(&when, &now, rxi_SendDelayedAck, call, 0);
- }
/* we've damaged this call already, might as well do it in. */
return np;
}
rxevent_Cancel(call->delayedAckEvent, call, RX_CALL_REFCOUNT_DELAY);
np = rxi_SendAck(call, np, serial, RX_ACK_IDLE, istack);
} else if (call->nSoftAcks) {
- clock_GetTime(&now);
- when = now;
- if (haveLast && !(flags & RX_CLIENT_INITIATED)) {
- clock_Add(&when, &rx_lastAckDelay);
- } else {
- clock_Add(&when, &rx_softAckDelay);
- }
- if (!call->delayedAckEvent
- || clock_Gt(&call->delayedAckEvent->eventTime, &when)) {
- rxevent_Cancel(call->delayedAckEvent, call,
- RX_CALL_REFCOUNT_DELAY);
- MUTEX_ENTER(&rx_refcnt_mutex);
- CALL_HOLD(call, RX_CALL_REFCOUNT_DELAY);
- MUTEX_EXIT(&rx_refcnt_mutex);
- call->delayedAckEvent =
- rxevent_PostNow(&when, &now, rxi_SendDelayedAck, call, 0);
- }
+ if (haveLast && !(flags & RX_CLIENT_INITIATED))
+ rxi_PostDelayedAckEvent(call, &rx_lastAckDelay);
+ else
+ rxi_PostDelayedAckEvent(call, &rx_softAckDelay);
} else if (call->flags & RX_CALL_RECEIVE_DONE) {
rxevent_Cancel(call->delayedAckEvent, call, RX_CALL_REFCOUNT_DELAY);
}
RX_CALL_REFCOUNT_DELAY);
rxi_SendAck(call, 0, 0, RX_ACK_DELAY, 0);
} else {
- struct clock when, now;
- clock_GetTime(&now);
- when = now;
/* Delay to consolidate ack packets */
- clock_Add(&when, &rx_hardAckDelay);
- if (!call->delayedAckEvent
- || clock_Gt(&call->delayedAckEvent->
- eventTime, &when)) {
- rxevent_Cancel(call->delayedAckEvent,
- call,
- RX_CALL_REFCOUNT_DELAY);
- MUTEX_ENTER(&rx_refcnt_mutex);
- CALL_HOLD(call, RX_CALL_REFCOUNT_DELAY);
- MUTEX_EXIT(&rx_refcnt_mutex);
- call->delayedAckEvent =
- rxevent_PostNow(&when, &now,
- rxi_SendDelayedAck, call,
- 0);
- }
+ rxi_PostDelayedAckEvent(call,
+ &rx_hardAckDelay);
}
}
break;
rxi_SendAck(call, 0, serial, RX_ACK_DELAY, 0);
didHardAck = 1;
} else {
- struct clock when, now;
- clock_GetTime(&now);
- when = now;
/* Delay to consolidate ack packets */
- clock_Add(&when, &rx_hardAckDelay);
- if (!call->delayedAckEvent
- || clock_Gt(&call->delayedAckEvent->eventTime, &when)) {
- rxevent_Cancel(call->delayedAckEvent, call,
- RX_CALL_REFCOUNT_DELAY);
- MUTEX_ENTER(&rx_refcnt_mutex);
- CALL_HOLD(call, RX_CALL_REFCOUNT_DELAY);
- MUTEX_EXIT(&rx_refcnt_mutex);
- call->delayedAckEvent =
- rxevent_PostNow(&when, &now, rxi_SendDelayedAck, call, 0);
- }
+ rxi_PostDelayedAckEvent(call, &rx_hardAckDelay);
}
}
return didHardAck;