From cf5306cb160828b8d5fd8a7056eaf01f13aae683 Mon Sep 17 00:00:00 2001
From: deuce <>
Date: Tue, 7 Feb 2006 04:23:14 +0000
Subject: [PATCH] Fix bug exposed by most recent MSS auto-tuning. If the
 ringbuffer held more data than the linear buffer COULD hold, both semaphores
 would end up clear, and the data would never be sent.

Fix is to not wait on the semaphore unless the ringbuffer isn't
"full enough"
---
 src/sbbs3/main.cpp  | 16 ++++++++++++----
 src/sbbs3/websrvr.c | 21 +++++++++++++++------
 2 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp
index e48e38bc93..ac0bcfb2b4 100644
--- a/src/sbbs3/main.cpp
+++ b/src/sbbs3/main.cpp
@@ -1504,16 +1504,24 @@ void output_thread(void* arg)
 		 */
 		if(bufbot == buftop) {
 			/* Wait for something to output in the RingBuffer */
-			if(sem_trywait_block(&sbbs->outbuf.sem,1000))
-				continue;
+			if(!RingBufFull(&sbbs->outbuf)) {
+				if(sem_trywait_block(&sbbs->outbuf.sem,1000))
+					continue;
+			}
+			else
+				sem_trywait(&sbbs->outbuf.sem);
 
 			/* Check for spurious sem post... */
 			if(!RingBufFull(&sbbs->outbuf))
 				continue;
 
 			/* Wait for full buffer or drain timeout */
-			if(sbbs->outbuf.highwater_mark)
-				sem_trywait_block(&sbbs->outbuf.highwater_sem,startup->outbuf_drain_timeout);
+			if(RingBufFull(&sbbs->outbuf)<sbbs->outbuf.highwater_mark) {
+				if(sbbs->outbuf.highwater_mark)
+					sem_trywait_block(&sbbs->outbuf.highwater_sem,startup->outbuf_drain_timeout);
+			}
+			else
+				sem_trywait(&sbbs->outbuf.highwater_sem);
 
 			/*
 			 * At this point, there's something to send and,
diff --git a/src/sbbs3/websrvr.c b/src/sbbs3/websrvr.c
index e03d257fba..1769812d45 100644
--- a/src/sbbs3/websrvr.c
+++ b/src/sbbs3/websrvr.c
@@ -3868,7 +3868,7 @@ void http_output_thread(void *arg)
 		if(!getsockopt(session->socket, IPPROTO_TCP, TCP_MAXSEG, &i, &sl)) {
 			/* Check for sanity... */
 			if(i>100) {
-				obuf->highwater_mark=i;
+				obuf->highwater_mark=i-12;
 				lprintf(LOG_DEBUG,"Autotuning outbuf highwater mark to %d based on MSS",i);
 				mss=obuf->highwater_mark;
 				if(mss>OUTBUF_LEN) {
@@ -3882,17 +3882,26 @@ void http_output_thread(void *arg)
 
 	thread_up(TRUE /* setuid */);
     while(session->socket!=INVALID_SOCKET && !terminate_server) {
+
         /* Wait for something to output in the RingBuffer */
-        if(sem_trywait_block(&obuf->sem,1000))
-            continue;
+        if(!RingBufFull(obuf)) {
+			if(sem_trywait_block(&obuf->sem,1000))
+	            continue;
+		}
+		else
+			sem_trywait(&obuf->sem);
 
         /* Check for spurious sem post... */
         if(!RingBufFull(obuf))
             continue;
 
         /* Wait for full buffer or drain timeout */
-        if(obuf->highwater_mark)
-            sem_trywait_block(&obuf->highwater_sem,startup->outbuf_drain_timeout);
+		if(RingBufFull(obuf)<obuf->highwater_mark) {
+	        if(obuf->highwater_mark)
+    	        sem_trywait_block(&obuf->highwater_sem,startup->outbuf_drain_timeout);
+		}
+		else
+			sem_trywait(&obuf->highwater_sem);
 
         /*
          * At this point, there's something to send and,
@@ -3902,7 +3911,7 @@ void http_output_thread(void *arg)
          */
         len=avail=RingBufFull(obuf);
 		if(avail>mss)
-			len=avail=mss;
+			len=(avail=mss);
 
 		/* 
 		 * Read the current value of write_chunked... since we wait until the
-- 
GitLab