Consistently check for unsent data on the stream queues.

MFC after:	3 days
This commit is contained in:
Michael Tuexen 2016-08-07 23:04:46 +00:00
parent df31593d00
commit 124d851acf
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=303819
2 changed files with 16 additions and 18 deletions

View File

@ -221,18 +221,18 @@ sctp_is_there_unsent_data(struct sctp_tcb *stcb, int so_locked
#endif
)
{
int unsent_data = 0;
int unsent_data;
unsigned int i;
struct sctp_stream_queue_pending *sp;
struct sctp_association *asoc;
/*
* This function returns the number of streams that have true unsent
* data on them. Note that as it looks through it will clean up any
* places that have old data that has been sent but left at top of
* stream queue.
* This function returns if any stream has true unsent data on it.
* Note that as it looks through it will clean up any places that
* have old data that has been sent but left at top of stream queue.
*/
asoc = &stcb->asoc;
unsent_data = 0;
SCTP_TCB_SEND_LOCK(stcb);
if (!stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
/* Check to see if some data queued */
@ -270,8 +270,13 @@ sctp_is_there_unsent_data(struct sctp_tcb *stcb, int so_locked
sp->data = NULL;
}
sctp_free_a_strmoq(stcb, sp, so_locked);
if (!TAILQ_EMPTY(&stcb->asoc.strmout[i].outqueue)) {
unsent_data++;
}
} else {
unsent_data++;
}
if (unsent_data > 0) {
break;
}
}
@ -1049,7 +1054,7 @@ sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp SCTP_UNUSED,
#ifdef INVARIANTS
if (!TAILQ_EMPTY(&asoc->send_queue) ||
!TAILQ_EMPTY(&asoc->sent_queue) ||
!stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
sctp_is_there_unsent_data(stcb, SCTP_SO_NOT_LOCKED)) {
panic("Queues are not empty when handling SHUTDOWN-ACK");
}
#endif
@ -3215,7 +3220,7 @@ sctp_handle_shutdown_complete(struct sctp_shutdown_complete_chunk *cp SCTP_UNUSE
#ifdef INVARIANTS
if (!TAILQ_EMPTY(&asoc->send_queue) ||
!TAILQ_EMPTY(&asoc->sent_queue) ||
!stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
sctp_is_there_unsent_data(stcb, SCTP_SO_NOT_LOCKED)) {
panic("Queues are not empty when handling SHUTDOWN-COMPLETE");
}
#endif

View File

@ -6687,13 +6687,9 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
asoc = &stcb->asoc;
if (ca->sndrcv.sinfo_flags & SCTP_EOF) {
/* shutdown this assoc */
int cnt;
cnt = sctp_is_there_unsent_data(stcb, SCTP_SO_NOT_LOCKED);
if (TAILQ_EMPTY(&asoc->send_queue) &&
TAILQ_EMPTY(&asoc->sent_queue) &&
(cnt == 0)) {
sctp_is_there_unsent_data(stcb, SCTP_SO_NOT_LOCKED) == 0) {
if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete) (stcb, asoc)) {
goto abort_anyway;
}
@ -7902,7 +7898,7 @@ sctp_med_chunk_output(struct sctp_inpcb *inp,
(asoc->ctrl_queue_cnt == stcb->asoc.ecn_echo_cnt_onq)) &&
TAILQ_EMPTY(&asoc->asconf_send_queue) &&
TAILQ_EMPTY(&asoc->send_queue) &&
stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
sctp_is_there_unsent_data(stcb, so_locked) == 0) {
nothing_to_send:
*reason_code = 9;
return (0);
@ -10185,7 +10181,7 @@ sctp_chunk_output(struct sctp_inpcb *inp,
}
if (TAILQ_EMPTY(&asoc->control_send_queue) &&
TAILQ_EMPTY(&asoc->send_queue) &&
stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
sctp_is_there_unsent_data(stcb, so_locked) == 0) {
/* Nothing left to send */
break;
}
@ -13455,18 +13451,15 @@ sctp_lower_sosend(struct socket *so,
/* EOF thing ? */
if ((srcv->sinfo_flags & SCTP_EOF) &&
(got_all_of_the_send == 1)) {
int cnt;
SCTP_STAT_INCR(sctps_sends_with_eof);
error = 0;
if (hold_tcblock == 0) {
SCTP_TCB_LOCK(stcb);
hold_tcblock = 1;
}
cnt = sctp_is_there_unsent_data(stcb, SCTP_SO_LOCKED);
if (TAILQ_EMPTY(&asoc->send_queue) &&
TAILQ_EMPTY(&asoc->sent_queue) &&
(cnt == 0)) {
sctp_is_there_unsent_data(stcb, SCTP_SO_LOCKED) == 0) {
if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete) (stcb, asoc)) {
goto abort_anyway;
}