X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2Frmr%2Fcommon%2Fsrc%2Fring_static.c;h=7170a9d0795caadaa191673891f8f67a699f5ffa;hb=ce1c741c01e8387cb095dac5e36a4d8ad91d006d;hp=8e565fabb47de9009ab3275f8e1c62fc8c138e60;hpb=d324fe4bfea9daa22aa16c605bd3157a875a8ccd;p=ric-plt%2Flib%2Frmr.git diff --git a/src/rmr/common/src/ring_static.c b/src/rmr/common/src/ring_static.c index 8e565fa..7170a9d 100644 --- a/src/rmr/common/src/ring_static.c +++ b/src/rmr/common/src/ring_static.c @@ -75,6 +75,7 @@ static void* uta_mk_ring( int size ) { return NULL; } + r->flags = 0; r->rgate = NULL; r->wgate = NULL; r->head = r->tail = 0; @@ -124,7 +125,7 @@ static int uta_ring_config( void* vr, int options ) { } } - if( options & RING_RLOCK ) { + if( options & (RING_RLOCK | RING_FRLOCK) ) { // read locking if( r->rgate == NULL ) { // don't realloc r->rgate = (pthread_mutex_t *) malloc( sizeof( *r->rgate ) ); if( r->rgate == NULL ) { @@ -133,6 +134,9 @@ static int uta_ring_config( void* vr, int options ) { pthread_mutex_init( r->rgate, NULL ); } + if( options & RING_FRLOCK ) { + r->flags |= RING_FL_FLOCK; + } } return 1; @@ -188,8 +192,16 @@ static inline void* uta_ring_extract( void* vr ) { return NULL; } - if( r->rgate != NULL ) { // if lock exists we must honour it - pthread_mutex_lock( r->rgate ); + if( r->rgate != NULL ) { // if lock exists we must honour it + if( r->flags & RING_FL_FLOCK ) { // fast read locking try once and return nil if we cant lock + if( pthread_mutex_trylock( r->rgate ) != 0 ) { // quick fail if not able to get a lock + return NULL; + } + } else { + if( pthread_mutex_lock( r->rgate ) != 0 ) { + return NULL; + } + } if( r->tail == r->head ) { // ensure ring didn't go empty while waiting pthread_mutex_unlock( r->rgate ); return NULL; @@ -219,9 +231,13 @@ future -- investigate if it's possible only to set/clear when empty or going to return data; } + /* Insert the pointer at the next open space in the ring. - Returns 1 if the inert was ok, and 0 if the ring is full. + Returns 1 if the inert was ok, and 0 if there is an error; + errno will be set to EXFULL if the ring is full, if the attempt + fails with anyt other error that indicates the inability to obtain + a lock on the ring. */ static inline int uta_ring_insert( void* vr, void* new_data ) { ring_t* r; @@ -236,13 +252,16 @@ static inline int uta_ring_insert( void* vr, void* new_data ) { } if( r->wgate != NULL ) { // if lock exists we must honour it - pthread_mutex_lock( r->wgate ); + if( pthread_mutex_lock( r->wgate ) != 0 ) { + return 0; // leave mutex reason in place + } } if( r->head+1 == r->tail || (r->head+1 >= r->nelements && !r->tail) ) { // ring is full - if( r->wgate != NULL ) { // ensure released if needed + if( r->wgate != NULL ) { // ensure released if needed pthread_mutex_unlock( r->wgate ); } + errno = EXFULL; return 0; }