call->tqc -=
#endif /* RXDEBUG_PACKET */
rxi_FreePackets(0, &call->tq);
+ if (call->tqWaiters || (call->flags & RX_CALL_TQ_WAIT)) {
+#ifdef RX_ENABLE_LOCKS
+ CV_BROADCAST(&call->cv_tq);
+#else /* RX_ENABLE_LOCKS */
+ osi_rxWakeup(&call->tq);
+#endif /* RX_ENABLE_LOCKS */
+ }
#ifdef AFS_GLOBAL_RXLOCK_KERNEL
call->flags &= ~RX_CALL_TQ_CLEARME;
}
dpf(("rcall %"AFS_PTR_FMT" has %d waiters and flags %d\n", call, call->tqWaiters, call->flags));
}
call->flags = 0;
- while (call->tqWaiters) {
-#ifdef RX_ENABLE_LOCKS
- CV_BROADCAST(&call->cv_tq);
-#else /* RX_ENABLE_LOCKS */
- osi_rxWakeup(&call->tq);
-#endif /* RX_ENABLE_LOCKS */
- call->tqWaiters--;
- }
}
rxi_ClearReceiveQueue(call);
RX_CLIENT_CONNECTION ? rx_socket : conn->service->socket);
- MUTEX_ENTER(&conn->conn_data_lock);
- conn->natKeepAliveEvent = NULL;
- MUTEX_EXIT(&conn->conn_data_lock);
-
tp = &tbuffer[sizeof(struct rx_header)];
taddr.sin_family = AF_INET;
taddr.sin_port = rx_PortOf(rx_PeerOf(conn));
tmpiov[0].iov_len = 1 + sizeof(struct rx_header);
osi_NetSend(socket, &taddr, tmpiov, 1, 1 + sizeof(struct rx_header), 1);
- rxi_ScheduleNatKeepAliveEvent(conn);
+
+ MUTEX_ENTER(&conn->conn_data_lock);
+ /* Only reschedule ourselves if the connection would not be destroyed */
+ if (conn->refCount <= 1) {
+ conn->natKeepAliveEvent = NULL;
+ MUTEX_EXIT(&conn->conn_data_lock);
+ rx_DestroyConnection(conn); /* drop the reference for this */
+ } else {
+ conn->natKeepAliveEvent = NULL;
+ conn->refCount--; /* drop the reference for this */
+ rxi_ScheduleNatKeepAliveEvent(conn);
+ MUTEX_EXIT(&conn->conn_data_lock);
+ }
}
void
rxi_ScheduleNatKeepAliveEvent(struct rx_connection *conn)
{
- MUTEX_ENTER(&conn->conn_data_lock);
if (!conn->natKeepAliveEvent && conn->secondsUntilNatPing) {
struct clock when, now;
clock_GetTime(&now);
when = now;
when.sec += conn->secondsUntilNatPing;
+ conn->refCount++; /* hold a reference for this */
conn->natKeepAliveEvent =
rxevent_PostNow(&when, &now, rxi_NatKeepAliveEvent, conn, 0);
}
- MUTEX_EXIT(&conn->conn_data_lock);
}
void
rx_SetConnSecondsUntilNatPing(struct rx_connection *conn, afs_int32 seconds)
{
+ MUTEX_ENTER(&conn->conn_data_lock);
conn->secondsUntilNatPing = seconds;
if (seconds != 0)
rxi_ScheduleNatKeepAliveEvent(conn);
+ MUTEX_EXIT(&conn->conn_data_lock);
}
void
rxi_NatKeepAliveOn(struct rx_connection *conn)
{
+ MUTEX_ENTER(&conn->conn_data_lock);
rxi_ScheduleNatKeepAliveEvent(conn);
+ MUTEX_EXIT(&conn->conn_data_lock);
}
/* When a call is in progress, this routine is called occasionally to