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