# include "rx/rx_kernel.h"
# include "afs/lock.h"
#else /* KERNEL */
-# include <sys/types.h>
-# include <string.h>
-# ifdef AFS_NT40_ENV
-# include <winsock2.h>
-# else /* !AFS_NT40_ENV */
-# include <sys/socket.h>
-# include <sys/file.h>
-# include <netdb.h>
-# include <netinet/in.h>
-# include <sys/stat.h>
-# include <sys/time.h>
-# include <unistd.h>
-# endif /* !AFS_NT40_ENV */
+# include <roken.h>
#endif /* KERNEL */
#include "rx.h"
#include "rx_clock.h"
#include "rx_queue.h"
#include "rx_globals.h"
+#include "rx_atomic.h"
+#include "rx_internal.h"
+#include "rx_conn.h"
+#include "rx_call.h"
+#include "rx_packet.h"
#ifdef RX_LOCKS_DB
/* rxdb_fileID is used to identify the lock location, along with line#. */
rxi_ReadProc(struct rx_call *call, char *buf,
int nbytes)
{
- struct rx_packet *cp = call->currentPacket;
struct rx_packet *rp;
int requestCount;
unsigned int t;
return 0;
}
call->rnext++;
- cp = call->currentPacket = rp;
+ call->currentPacket = rp;
#ifdef RX_TRACK_PACKETS
call->currentPacket->flags |= RX_PKTFLAG_CP;
#endif
/* begin at the beginning [ more or less ], continue
* on until the end, then stop. */
call->curpos =
- (char *)cp->wirevec[1].iov_base +
+ (char *) call->currentPacket->wirevec[1].iov_base +
call->conn->securityHeaderSize;
call->curlen =
- cp->wirevec[1].iov_len -
+ call->currentPacket->wirevec[1].iov_len -
call->conn->securityHeaderSize;
/* Notice that this code works correctly if the data
* (no yields, etc.). If it didn't, this would be a
* problem because a value of zero for call->nLeft
* normally means that there is no read packet */
- call->nLeft = cp->length;
- hadd32(call->bytesRcvd, cp->length);
+ call->nLeft = call->currentPacket->length;
+ hadd32(call->bytesRcvd, call->currentPacket->length);
/* Send a hard ack for every rxi_HardAckRate+1 packets
* consumed. Otherwise schedule an event to send
call->nHardAcks++;
if (!(call->flags & RX_CALL_RECEIVE_DONE)) {
if (call->nHardAcks > (u_short) rxi_HardAckRate) {
- rxevent_Cancel(call->delayedAckEvent, call,
+ rxevent_Cancel(&call->delayedAckEvent, call,
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;
osi_rxSleep(&call->rq);
#endif
}
- cp = call->currentPacket;
call->startWait = 0;
#ifdef RX_ENABLE_LOCKS
* number of bytes read in the length field of the packet struct. On
* the final portion of a received packet, it's almost certain that
* call->nLeft will be smaller than the final buffer. */
- while (nbytes && cp) {
+ while (nbytes && call->currentPacket) {
t = MIN((int)call->curlen, nbytes);
t = MIN(t, (int)call->nLeft);
memcpy(buf, call->curpos, t);
#ifdef RX_TRACK_PACKETS
call->currentPacket->flags &= ~RX_PKTFLAG_CP;
#endif
- rxi_FreePacket(cp);
- cp = call->currentPacket = (struct rx_packet *)0;
+ rxi_FreePacket(call->currentPacket);
+ call->currentPacket = NULL;
} else if (!call->curlen) {
/* need to get another struct iov */
- if (++call->curvec >= cp->niovecs) {
+ if (++call->curvec >= call->currentPacket->niovecs) {
/* current packet is exhausted, get ready for another */
/* don't worry about curvec and stuff, they get set somewhere else */
#ifdef RX_TRACK_PACKETS
call->currentPacket->flags &= ~RX_PKTFLAG_CP;
#endif
- rxi_FreePacket(cp);
- cp = call->currentPacket = (struct rx_packet *)0;
+ rxi_FreePacket(call->currentPacket);
+ call->currentPacket = NULL;
call->nLeft = 0;
} else {
call->curpos =
- (char *)cp->wirevec[call->curvec].iov_base;
- call->curlen = cp->wirevec[call->curvec].iov_len;
+ call->currentPacket->wirevec[call->curvec].iov_base;
+ call->curlen =
+ call->currentPacket->wirevec[call->curvec].iov_len;
}
}
}
rx_ReadProc(struct rx_call *call, char *buf, int nbytes)
{
int bytes;
- int tcurlen;
- int tnLeft;
- char *tcurpos;
SPLVAR;
/* Free any packets from the last call to ReadvProc/WritevProc */
* Most common case, all of the data is in the current iovec.
* We are relying on nLeft being zero unless the call is in receive mode.
*/
- tcurlen = call->curlen;
- tnLeft = call->nLeft;
- if (!call->error && tcurlen > nbytes && tnLeft > nbytes) {
- tcurpos = call->curpos;
- memcpy(buf, tcurpos, nbytes);
+ if (!call->error && call->curlen > nbytes && call->nLeft > nbytes) {
+ memcpy(buf, call->curpos, nbytes);
- call->curpos = tcurpos + nbytes;
- call->curlen = tcurlen - nbytes;
- call->nLeft = tnLeft - nbytes;
+ call->curpos += nbytes;
+ call->curlen -= nbytes;
+ call->nLeft -= nbytes;
if (!call->nLeft && call->currentPacket != NULL) {
/* out of packet. Get another one. */
rx_ReadProc32(struct rx_call *call, afs_int32 * value)
{
int bytes;
- int tcurlen;
- int tnLeft;
- char *tcurpos;
SPLVAR;
/* Free any packets from the last call to ReadvProc/WritevProc */
* Most common case, all of the data is in the current iovec.
* We are relying on nLeft being zero unless the call is in receive mode.
*/
- tcurlen = call->curlen;
- tnLeft = call->nLeft;
- if (!call->error && tcurlen >= sizeof(afs_int32)
- && tnLeft >= sizeof(afs_int32)) {
- tcurpos = call->curpos;
+ if (!call->error && call->curlen >= sizeof(afs_int32)
+ && call->nLeft >= sizeof(afs_int32)) {
- memcpy((char *)value, tcurpos, sizeof(afs_int32));
+ memcpy((char *)value, call->curpos, sizeof(afs_int32));
+
+ call->curpos += sizeof(afs_int32);
+ call->curlen -= sizeof(afs_int32);
+ call->nLeft -= sizeof(afs_int32);
- call->curpos = tcurpos + sizeof(afs_int32);
- call->curlen = (u_short)(tcurlen - sizeof(afs_int32));
- call->nLeft = (u_short)(tnLeft - sizeof(afs_int32));
if (!call->nLeft && call->currentPacket != NULL) {
/* out of packet. Get another one. */
rxi_FreePacket(call->currentPacket);
int didHardAck = 0;
unsigned int t;
struct rx_packet *rp;
- struct rx_packet *curp;
struct iovec *call_iov;
struct iovec *cur_iov = NULL;
- curp = call->currentPacket;
- if (curp) {
- cur_iov = &curp->wirevec[call->curvec];
+ if (call->currentPacket) {
+ cur_iov = &call->currentPacket->wirevec[call->curvec];
}
call_iov = &call->iov[call->iovNext];
return 1;
}
call->rnext++;
- curp = call->currentPacket = rp;
+ call->currentPacket = rp;
#ifdef RX_TRACK_PACKETS
call->currentPacket->flags |= RX_PKTFLAG_CP;
#endif
call->curvec = 1; /* 0th vec is always header */
- cur_iov = &curp->wirevec[1];
+ cur_iov = &call->currentPacket->wirevec[1];
/* begin at the beginning [ more or less ], continue
* on until the end, then stop. */
call->curpos =
- (char *)curp->wirevec[1].iov_base +
+ (char *)call->currentPacket->wirevec[1].iov_base +
call->conn->securityHeaderSize;
call->curlen =
- curp->wirevec[1].iov_len -
+ call->currentPacket->wirevec[1].iov_len -
call->conn->securityHeaderSize;
/* Notice that this code works correctly if the data
* (no yields, etc.). If it didn't, this would be a
* problem because a value of zero for call->nLeft
* normally means that there is no read packet */
- call->nLeft = curp->length;
- hadd32(call->bytesRcvd, curp->length);
+ call->nLeft = call->currentPacket->length;
+ hadd32(call->bytesRcvd, call->currentPacket->length);
/* Send a hard ack for every rxi_HardAckRate+1 packets
* consumed. Otherwise schedule an event to send
* number of bytes read in the length field of the packet struct. On
* the final portion of a received packet, it's almost certain that
* call->nLeft will be smaller than the final buffer. */
- while (call->iovNBytes && call->iovNext < call->iovMax && curp) {
+ while (call->iovNBytes
+ && call->iovNext < call->iovMax
+ && call->currentPacket) {
t = MIN((int)call->curlen, call->iovNBytes);
t = MIN(t, (int)call->nLeft);
if (!call->nLeft) {
/* out of packet. Get another one. */
#ifdef RX_TRACK_PACKETS
- curp->flags &= ~RX_PKTFLAG_CP;
- curp->flags |= RX_PKTFLAG_IOVQ;
+ call->currentPacket->flags &= ~RX_PKTFLAG_CP;
+ call->currentPacket->flags |= RX_PKTFLAG_IOVQ;
#endif
- queue_Append(&call->iovq, curp);
+ queue_Append(&call->iovq, call->currentPacket);
#ifdef RXDEBUG_PACKET
call->iovqc++;
#endif /* RXDEBUG_PACKET */
- curp = call->currentPacket = (struct rx_packet *)0;
+ call->currentPacket = NULL;
} else if (!call->curlen) {
/* need to get another struct iov */
- if (++call->curvec >= curp->niovecs) {
+ if (++call->curvec >= call->currentPacket->niovecs) {
/* current packet is exhausted, get ready for another */
/* don't worry about curvec and stuff, they get set somewhere else */
#ifdef RX_TRACK_PACKETS
- curp->flags &= ~RX_PKTFLAG_CP;
- curp->flags |= RX_PKTFLAG_IOVQ;
+ call->currentPacket->flags &= ~RX_PKTFLAG_CP;
+ call->currentPacket->flags |= RX_PKTFLAG_IOVQ;
#endif
- queue_Append(&call->iovq, curp);
+ queue_Append(&call->iovq, call->currentPacket);
#ifdef RXDEBUG_PACKET
call->iovqc++;
#endif /* RXDEBUG_PACKET */
- curp = call->currentPacket = (struct rx_packet *)0;
+ call->currentPacket = NULL;
call->nLeft = 0;
} else {
cur_iov++;
* send a hard ack. */
if (didConsume && (!(call->flags & RX_CALL_RECEIVE_DONE))) {
if (call->nHardAcks > (u_short) rxi_HardAckRate) {
- rxevent_Cancel(call->delayedAckEvent, call,
+ rxevent_Cancel(&call->delayedAckEvent, call,
RX_CALL_REFCOUNT_DELAY);
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;
int nbytes)
{
struct rx_connection *conn = call->conn;
- struct rx_packet *cp = call->currentPacket;
unsigned int t;
int requestCount = nbytes;
if ((conn->type == RX_SERVER_CONNECTION)
&& (call->mode == RX_MODE_RECEIVING)) {
call->mode = RX_MODE_SENDING;
- if (cp) {
+ if (call->currentPacket) {
#ifdef RX_TRACK_PACKETS
- cp->flags &= ~RX_PKTFLAG_CP;
+ call->currentPacket->flags &= ~RX_PKTFLAG_CP;
#endif
- rxi_FreePacket(cp);
- cp = call->currentPacket = (struct rx_packet *)0;
+ rxi_FreePacket(call->currentPacket);
+ call->currentPacket = NULL;
call->nLeft = 0;
call->nFree = 0;
}
do {
if (call->nFree == 0) {
MUTEX_ENTER(&call->lock);
- cp = call->currentPacket;
if (call->error)
call->mode = RX_MODE_ERROR;
- if (!call->error && cp) {
- /* Clear the current packet now so that if
- * we are forced to wait and drop the lock
- * the packet we are planning on using
- * cannot be freed.
- */
-#ifdef RX_TRACK_PACKETS
- cp->flags &= ~RX_PKTFLAG_CP;
-#endif
- call->currentPacket = (struct rx_packet *)0;
+ if (!call->error && call->currentPacket) {
clock_NewTime(); /* Bogus: need new time package */
/* The 0, below, specifies that it is not the last packet:
* there will be others. PrepareSendPacket may
* alter the packet length by up to
* conn->securityMaxTrailerSize */
- hadd32(call->bytesSent, cp->length);
- rxi_PrepareSendPacket(call, cp, 0);
+ hadd32(call->bytesSent, call->currentPacket->length);
+ rxi_PrepareSendPacket(call, call->currentPacket, 0);
#ifdef AFS_GLOBAL_RXLOCK_KERNEL
/* PrepareSendPacket drops the call lock */
rxi_WaitforTQBusy(call);
#endif /* AFS_GLOBAL_RXLOCK_KERNEL */
#ifdef RX_TRACK_PACKETS
- cp->flags |= RX_PKTFLAG_TQ;
+ call->currentPacket->flags |= RX_PKTFLAG_TQ;
#endif
- queue_Append(&call->tq, cp);
+ queue_Append(&call->tq, call->currentPacket);
#ifdef RXDEBUG_PACKET
call->tqc++;
#endif /* RXDEBUG_PACKET */
- cp = (struct rx_packet *)0;
- if (!
- (call->
- flags & (RX_CALL_FAST_RECOVER |
- RX_CALL_FAST_RECOVER_WAIT))) {
- rxi_Start(0, call, 0, 0);
+#ifdef RX_TRACK_PACKETS
+ call->currentPacket->flags &= ~RX_PKTFLAG_CP;
+#endif
+ call->currentPacket = NULL;
+
+ /* If the call is in recovery, let it exhaust its current
+ * retransmit queue before forcing it to send new packets
+ */
+ if (!(call->flags & (RX_CALL_FAST_RECOVER))) {
+ rxi_Start(call, 0);
}
- } else if (cp) {
+ } else if (call->currentPacket) {
#ifdef RX_TRACK_PACKETS
- cp->flags &= ~RX_PKTFLAG_CP;
+ call->currentPacket->flags &= ~RX_PKTFLAG_CP;
#endif
- rxi_FreePacket(cp);
- cp = call->currentPacket = (struct rx_packet *)0;
+ rxi_FreePacket(call->currentPacket);
+ call->currentPacket = NULL;
}
/* Wait for transmit window to open up */
while (!call->error
}
#endif /* RX_ENABLE_LOCKS */
}
- if ((cp = rxi_AllocSendPacket(call, nbytes))) {
+ if ((call->currentPacket = rxi_AllocSendPacket(call, nbytes))) {
#ifdef RX_TRACK_PACKETS
- cp->flags |= RX_PKTFLAG_CP;
+ call->currentPacket->flags |= RX_PKTFLAG_CP;
#endif
- call->currentPacket = cp;
- call->nFree = cp->length;
+ call->nFree = call->currentPacket->length;
call->curvec = 1; /* 0th vec is always header */
/* begin at the beginning [ more or less ], continue
* on until the end, then stop. */
call->curpos =
- (char *)cp->wirevec[1].iov_base +
+ (char *) call->currentPacket->wirevec[1].iov_base +
call->conn->securityHeaderSize;
call->curlen =
- cp->wirevec[1].iov_len - call->conn->securityHeaderSize;
+ call->currentPacket->wirevec[1].iov_len -
+ call->conn->securityHeaderSize;
}
if (call->error) {
call->mode = RX_MODE_ERROR;
- if (cp) {
+ if (call->currentPacket) {
#ifdef RX_TRACK_PACKETS
- cp->flags &= ~RX_PKTFLAG_CP;
+ call->currentPacket->flags &= ~RX_PKTFLAG_CP;
#endif
- rxi_FreePacket(cp);
+ rxi_FreePacket(call->currentPacket);
call->currentPacket = NULL;
}
MUTEX_EXIT(&call->lock);
MUTEX_EXIT(&call->lock);
}
- if (cp && (int)call->nFree < nbytes) {
+ if (call->currentPacket && (int)call->nFree < nbytes) {
/* Try to extend the current buffer */
int len, mud;
- len = cp->length;
+ len = call->currentPacket->length;
mud = rx_MaxUserDataSize(call);
if (mud > len) {
int want;
want = MIN(nbytes - (int)call->nFree, mud - len);
- rxi_AllocDataBuf(cp, want, RX_PACKET_CLASS_SEND_CBUF);
- if (cp->length > (unsigned)mud)
- cp->length = mud;
- call->nFree += (cp->length - len);
+ rxi_AllocDataBuf(call->currentPacket, want,
+ RX_PACKET_CLASS_SEND_CBUF);
+ if (call->currentPacket->length > (unsigned)mud)
+ call->currentPacket->length = mud;
+ call->nFree += (call->currentPacket->length - len);
}
}
* and return. Don't ship a buffer that's full immediately to
* the peer--we don't know if it's the last buffer yet */
- if (!cp) {
+ if (!call->currentPacket) {
call->nFree = 0;
}
if (!call->curlen) {
/* need to get another struct iov */
- if (++call->curvec >= cp->niovecs) {
+ if (++call->curvec >= call->currentPacket->niovecs) {
/* current packet is full, extend or send it */
call->nFree = 0;
} else {
- call->curpos = (char *)cp->wirevec[call->curvec].iov_base;
- call->curlen = cp->wirevec[call->curvec].iov_len;
+ call->curpos =
+ call->currentPacket->wirevec[call->curvec].iov_base;
+ call->curlen =
+ call->currentPacket->wirevec[call->curvec].iov_len;
}
}
} /* while bytes to send and room to send them */
* LOCKS USED -- called at netpri.
*/
-int
+static int
rxi_WritevAlloc(struct rx_call *call, struct iovec *iov, int *nio, int maxio,
int nbytes)
{
struct rx_connection *conn = call->conn;
- struct rx_packet *cp = call->currentPacket;
+ struct rx_packet *cp;
int requestCount;
int nextio;
/* Temporary values, real work is done in rxi_WritevProc */
if ((conn->type == RX_SERVER_CONNECTION)
&& (call->mode == RX_MODE_RECEIVING)) {
call->mode = RX_MODE_SENDING;
- if (cp) {
+ if (call->currentPacket) {
#ifdef RX_TRACK_PACKETS
- cp->flags &= ~RX_PKTFLAG_CP;
+ call->currentPacket->flags &= ~RX_PKTFLAG_CP;
#endif
- rxi_FreePacket(cp);
- cp = call->currentPacket = (struct rx_packet *)0;
+ rxi_FreePacket(call->currentPacket);
+ call->currentPacket = NULL;
call->nLeft = 0;
call->nFree = 0;
}
tcurvec = call->curvec;
tcurpos = call->curpos;
tcurlen = call->curlen;
+ cp = call->currentPacket;
do {
int t;
int
rxi_WritevProc(struct rx_call *call, struct iovec *iov, int nio, int nbytes)
{
- struct rx_packet *cp = NULL;
#ifdef RX_TRACK_PACKETS
struct rx_packet *p, *np;
#endif
#ifdef AFS_GLOBAL_RXLOCK_KERNEL
rxi_WaitforTQBusy(call);
#endif /* AFS_GLOBAL_RXLOCK_KERNEL */
- cp = call->currentPacket;
if (call->error) {
call->mode = RX_MODE_ERROR;
MUTEX_EXIT(&call->lock);
- if (cp) {
+ if (call->currentPacket) {
#ifdef RX_TRACK_PACKETS
- cp->flags &= ~RX_PKTFLAG_CP;
- cp->flags |= RX_PKTFLAG_IOVQ;
+ call->currentPacket->flags &= ~RX_PKTFLAG_CP;
+ call->currentPacket->flags |= RX_PKTFLAG_IOVQ;
#endif
- queue_Prepend(&call->iovq, cp);
+ queue_Prepend(&call->iovq, call->currentPacket);
#ifdef RXDEBUG_PACKET
call->iovqc++;
#endif /* RXDEBUG_PACKET */
- call->currentPacket = (struct rx_packet *)0;
+ call->currentPacket = NULL;
}
#ifdef RXDEBUG_PACKET
call->iovqc -=
tmpqc = 0;
#endif /* RXDEBUG_PACKET */
do {
- if (call->nFree == 0 && cp) {
+ if (call->nFree == 0 && call->currentPacket) {
clock_NewTime(); /* Bogus: need new time package */
/* The 0, below, specifies that it is not the last packet:
* there will be others. PrepareSendPacket may
* alter the packet length by up to
* conn->securityMaxTrailerSize */
- hadd32(call->bytesSent, cp->length);
- rxi_PrepareSendPacket(call, cp, 0);
+ hadd32(call->bytesSent, call->currentPacket->length);
+ rxi_PrepareSendPacket(call, call->currentPacket, 0);
#ifdef AFS_GLOBAL_RXLOCK_KERNEL
/* PrepareSendPacket drops the call lock */
rxi_WaitforTQBusy(call);
#endif /* AFS_GLOBAL_RXLOCK_KERNEL */
- queue_Append(&tmpq, cp);
+ queue_Append(&tmpq, call->currentPacket);
#ifdef RXDEBUG_PACKET
tmpqc++;
#endif /* RXDEBUG_PACKET */
- cp = call->currentPacket = (struct rx_packet *)0;
+ call->currentPacket = NULL;
/* The head of the iovq is now the current packet */
if (nbytes) {
rxi_FreePackets(0, &tmpq);
return 0;
}
- cp = queue_First(&call->iovq, rx_packet);
- queue_Remove(cp);
+ call->currentPacket = queue_First(&call->iovq, rx_packet);
+ queue_Remove(call->currentPacket);
#ifdef RX_TRACK_PACKETS
- cp->flags &= ~RX_PKTFLAG_IOVQ;
+ call->currentPacket->flags &= ~RX_PKTFLAG_IOVQ;
+ call->currentPacket->flags |= RX_PKTFLAG_CP;
#endif
#ifdef RXDEBUG_PACKET
call->iovqc--;
#endif /* RXDEBUG_PACKET */
-#ifdef RX_TRACK_PACKETS
- cp->flags |= RX_PKTFLAG_CP;
-#endif
- call->currentPacket = cp;
- call->nFree = cp->length;
+ call->nFree = call->currentPacket->length;
call->curvec = 1;
call->curpos =
- (char *)cp->wirevec[1].iov_base +
+ (char *) call->currentPacket->wirevec[1].iov_base +
call->conn->securityHeaderSize;
call->curlen =
- cp->wirevec[1].iov_len - call->conn->securityHeaderSize;
+ call->currentPacket->wirevec[1].iov_len -
+ call->conn->securityHeaderSize;
}
}
|| iov[nextio].iov_len > (int)call->curlen) {
call->error = RX_PROTOCOL_ERROR;
MUTEX_EXIT(&call->lock);
- if (cp) {
+ if (call->currentPacket) {
#ifdef RX_TRACK_PACKETS
- cp->flags &= ~RX_PKTFLAG_CP;
+ call->currentPacket->flags &= ~RX_PKTFLAG_CP;
#endif
- queue_Prepend(&tmpq, cp);
+ queue_Prepend(&tmpq, call->currentPacket);
#ifdef RXDEBUG_PACKET
tmpqc++;
#endif /* RXDEBUG_PACKET */
- cp = call->currentPacket = (struct rx_packet *)0;
+ call->currentPacket = NULL;
}
#ifdef RXDEBUG_PACKET
tmpqc -=
call->nFree -= iov[nextio].iov_len;
nextio++;
if (call->curlen == 0) {
- if (++call->curvec > cp->niovecs) {
+ if (++call->curvec > call->currentPacket->niovecs) {
call->nFree = 0;
} else {
- call->curpos = (char *)cp->wirevec[call->curvec].iov_base;
- call->curlen = cp->wirevec[call->curvec].iov_len;
+ call->curpos =
+ call->currentPacket->wirevec[call->curvec].iov_base;
+ call->curlen =
+ call->currentPacket->wirevec[call->curvec].iov_len;
}
}
}
queue_SpliceAppend(&call->tq, &tmpq);
- if (!(call->flags & (RX_CALL_FAST_RECOVER | RX_CALL_FAST_RECOVER_WAIT))) {
- rxi_Start(0, call, 0, 0);
+ /* If the call is in recovery, let it exhaust its current retransmit
+ * queue before forcing it to send new packets
+ */
+ if (!(call->flags & RX_CALL_FAST_RECOVER)) {
+ rxi_Start(call, 0);
}
/* Wait for the length of the transmit queue to fall below call->twind */
call->startWait = 0;
}
- /* cp is no longer valid since we may have given up the lock */
- cp = call->currentPacket;
-
if (call->error) {
call->mode = RX_MODE_ERROR;
call->currentPacket = NULL;
MUTEX_EXIT(&call->lock);
- if (cp) {
+ if (call->currentPacket) {
#ifdef RX_TRACK_PACKETS
- cp->flags &= ~RX_PKTFLAG_CP;
+ call->currentPacket->flags &= ~RX_PKTFLAG_CP;
#endif
- rxi_FreePacket(cp);
+ rxi_FreePacket(call->currentPacket);
}
return 0;
}
#ifdef RXDEBUG_PACKET
call->tqc++;
#endif /* RXDEBUG_PACKET */
- if (!
- (call->
- flags & (RX_CALL_FAST_RECOVER | RX_CALL_FAST_RECOVER_WAIT))) {
- rxi_Start(0, call, 0, 0);
+
+ /* If the call is in recovery, let it exhaust its current retransmit
+ * queue before forcing it to send new packets
+ */
+ if (!(call->flags & RX_CALL_FAST_RECOVER)) {
+ rxi_Start(call, 0);
}
MUTEX_EXIT(&call->lock);
}