diff options
author | Jérémy Zurcher <jeremy@asynk.ch> | 2010-01-06 23:45:20 +0100 |
---|---|---|
committer | Jérémy Zurcher <jeremy@asynk.ch> | 2010-01-06 23:45:20 +0100 |
commit | 82a5bc70e5f85d7d40e04e6a7dc567b086025421 (patch) | |
tree | 6f6eb3ec2a9bf27e180dc264abe4802bc2d0b1c0 /lf_ring_buffer.c | |
parent | ce1dcb6ed32396910e3400e3a816b76d22d5a0de (diff) | |
download | lock_free-82a5bc70e5f85d7d40e04e6a7dc567b086025421.zip lock_free-82a5bc70e5f85d7d40e04e6a7dc567b086025421.tar.gz |
ring buffer read : set read_from=-1 if read_from==write_to
Diffstat (limited to 'lf_ring_buffer.c')
-rw-r--r-- | lf_ring_buffer.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/lf_ring_buffer.c b/lf_ring_buffer.c index 75b2f17..ad866e0 100644 --- a/lf_ring_buffer.c +++ b/lf_ring_buffer.c @@ -149,8 +149,15 @@ int lf_ring_buffer_read( lf_ring_buffer_t *r, void *data, int flags ) { if (next==r->n_buf) next=0; /* will do bad things if data dst buffer is too small !! */ memcpy( data, r->buffer[idx].data, LFRB_DATA_SIZE ); - _LOG_( "write: CAS %d %d %d\n", r->read_from, idx, next ); - if( CompareAndSwapInt( &r->read_from, idx, next ) ) break; + _LOG_( "read: CAS %d %d %d\n", r->read_from, idx, next ); + if( CompareAndSwapInt( &r->read_from, idx, next ) ) { + if(r->read_from==r->write_to) { + /* the buffer is actually empty but writers will see it as full */ + _LOG_( "read: empty CAS %d %d %d\n", r->read_from, next, -1 ); + CompareAndSwapInt( &r->read_from, next, -1 ); + } + break; + } } else { _LOG_("read: not available\n"); if(IS_NOT_BLOCKING(flags)) return -1; |