--- sbbs/sbbs3/ringbuf.c 2018/04/24 16:39:34 1.1 +++ sbbs/sbbs3/ringbuf.c 2018/04/24 16:40:08 1.1.1.2 @@ -2,13 +2,13 @@ /* Synchronet ring buffer routines */ -/* $Id: ringbuf.c,v 1.1 2018/04/24 16:39:34 root Exp $ */ +/* $Id: ringbuf.c,v 1.1.1.2 2018/04/24 16:40:08 root Exp $ */ /**************************************************************************** * @format.tab-size 4 (Plain Text/Source Code File Header) * * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * * * - * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html * + * Copyright 2003 Rob Swindell - http://www.synchro.net/copyright.html * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * @@ -50,9 +50,15 @@ #ifdef RINGBUF_USE_STD_RTL #ifndef VTOOLSD - #include /* malloc prototype */ - #include /* memcpy prototype */ - #endif + + /* FreeBSD uses instead of */ + #ifdef __unix__ + #include + #else + #include /* malloc prototype */ + #endif + #include /* memcpy prototype */ + #endif /* !VTOOLSD */ #define os_malloc malloc #define rb_malloc malloc @@ -78,15 +84,23 @@ int RINGBUFCALL RingBufInit( RingBuf* rb #endif ) { - if((rb->pStart=(BYTE *)os_malloc(size))==NULL) + memset(rb,0,sizeof(RingBuf)); + if((rb->pStart=(BYTE *)os_malloc(size+1))==NULL) return(-1); #ifndef RINGBUF_USE_STD_RTL rb_free=os_free; rb_memcpy=os_memcpy; #endif rb->pHead=rb->pTail=rb->pStart; - rb->pEnd=rb->pStart+size-1; + rb->pEnd=rb->pStart+size; rb->size=size; +#ifdef RINGBUF_SEM + sem_init(&rb->sem,0,0); + sem_init(&rb->highwater_sem,0,0); +#endif +#ifdef RINGBUF_MUTEX + pthread_mutex_init(&rb->mutex,NULL); +#endif return(0); } @@ -94,6 +108,14 @@ void RINGBUFCALL RingBufDispose( RingBuf { if(rb->pStart!=NULL) os_free(rb->pStart); +#ifdef RINGBUF_SEM + sem_post(&rb->sem); /* just incase someone's waiting */ + sem_destroy(&rb->sem); + sem_destroy(&rb->highwater_sem); +#endif +#ifdef RINGBUF_MUTEX + pthread_mutex_destroy(&rb->mutex); +#endif memset(rb,0,sizeof(RingBuf)); } @@ -101,6 +123,10 @@ DWORD RINGBUFCALL RingBufFull( RingBuf* { DWORD head,tail,retval; +#ifdef RINGBUF_MUTEX + pthread_mutex_lock(&rb->mutex); +#endif + head = (DWORD) rb->pHead; tail = (DWORD) rb->pTail; @@ -109,6 +135,10 @@ DWORD RINGBUFCALL RingBufFull( RingBuf* else retval = rb->size - (tail - head); +#ifdef RINGBUF_MUTEX + pthread_mutex_unlock(&rb->mutex); +#endif + return(retval); } @@ -116,7 +146,7 @@ DWORD RINGBUFCALL RingBufFree( RingBuf* { DWORD retval; - retval = (rb->size - RingBufFull( rb ))-1; + retval = (rb->size - RingBufFull( rb )); return(retval); } @@ -128,6 +158,10 @@ DWORD RINGBUFCALL RingBufWrite( RingBuf* if(rb->pStart==NULL) return(0); +#ifdef RINGBUF_MUTEX + pthread_mutex_lock(&rb->mutex); +#endif + /* allowed to write at pEnd */ max = (((DWORD) rb->pEnd) - ((DWORD) rb->pHead)) + 1; @@ -158,6 +192,15 @@ DWORD RINGBUFCALL RingBufWrite( RingBuf* if(rb->pHead > rb->pEnd) rb->pHead = rb->pStart; +#ifdef RINGBUF_SEM + sem_post(&rb->sem); + if(rb->highwater_mark!=0 && RingBufFull(rb)>=rb->highwater_mark) + sem_post(&rb->highwater_sem); +#endif +#ifdef RINGBUF_MUTEX + pthread_mutex_unlock(&rb->mutex); +#endif + return(cnt); } @@ -170,6 +213,10 @@ DWORD RINGBUFCALL RingBufRead( RingBuf* if( len == 0 ) return(0); +#ifdef RINGBUF_MUTEX + pthread_mutex_lock(&rb->mutex); +#endif + if( len < cnt ) cnt = len; @@ -201,6 +248,17 @@ DWORD RINGBUFCALL RingBufRead( RingBuf* if(rb->pTail > rb->pEnd) rb->pTail = rb->pStart; +#ifdef RINGBUF_SEM /* clear semaphores, if appropriate */ + if(len-cnt==0) /* empty */ + sem_reset(&rb->sem); + if(len-cnthighwater_mark) + sem_reset(&rb->highwater_sem); +#endif + +#ifdef RINGBUF_MUTEX + pthread_mutex_unlock(&rb->mutex); +#endif + return(cnt); } @@ -212,6 +270,10 @@ DWORD RINGBUFCALL RingBufPeek( RingBuf* if( len == 0 ) return(0); +#ifdef RINGBUF_MUTEX + pthread_mutex_lock(&rb->mutex); +#endif + if( len < cnt ) cnt = len; @@ -233,13 +295,27 @@ DWORD RINGBUFCALL RingBufPeek( RingBuf* rb_memcpy( dst, rb->pStart, remain ); } +#ifdef RINGBUF_MUTEX + pthread_mutex_unlock(&rb->mutex); +#endif + return(cnt); } /* Reset head and tail pointers */ void RINGBUFCALL RingBufReInit(RingBuf* rb) { +#ifdef RINGBUF_MUTEX + pthread_mutex_lock(&rb->mutex); +#endif rb->pHead = rb->pTail = rb->pStart; +#ifdef RINGBUF_SEM + sem_reset(&rb->sem); + sem_reset(&rb->highwater_sem); +#endif +#ifdef RINGBUF_MUTEX + pthread_mutex_unlock(&rb->mutex); +#endif } /* End of RINGBUF.C */