libqb  0.16.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Macros | Typedefs | Functions
qbrb.h File Reference

This implements a ring buffer that works in "chunks" not bytes. More...

#include <sys/types.h>
#include <stdint.h>
Include dependency graph for qbrb.h:

Macros

#define QB_RB_FLAG_CREATE   0x01
 create a ring buffer (rather than open and existing one)
 
#define QB_RB_FLAG_OVERWRITE   0x02
 New calls to qb_rb_chunk_write() will call qb_rb_chunk_reclaim() if there is not enough space.
 
#define QB_RB_FLAG_SHARED_THREAD   0x04
 The ringbuffer will be shared between pthreads not processes.
 
#define QB_RB_FLAG_SHARED_PROCESS   0x08
 The ringbuffer will be shared between processes.
 
#define QB_RB_FLAG_NO_SEMAPHORE   0x10
 Don't use semaphores, only atomic ops.
 

Typedefs

typedef struct qb_ringbuffer_s qb_ringbuffer_t
 

Functions

qb_ringbuffer_tqb_rb_open (const char *name, size_t size, uint32_t flags, size_t shared_user_data_size)
 Create the ring buffer with the given type.
 
void qb_rb_close (qb_ringbuffer_t *rb)
 Dereference the ringbuffer and if we are the last user destroy it.
 
char * qb_rb_name_get (qb_ringbuffer_t *rb)
 Get the name of the ringbuffer.
 
void * qb_rb_shared_user_data_get (qb_ringbuffer_t *rb)
 Get a point to user shared data area.
 
ssize_t qb_rb_chunk_write (qb_ringbuffer_t *rb, const void *data, size_t len)
 Write a chunk to the ring buffer.
 
void * qb_rb_chunk_alloc (qb_ringbuffer_t *rb, size_t len)
 Allocate space for a chunk of the given size.
 
int32_t qb_rb_chunk_commit (qb_ringbuffer_t *rb, size_t len)
 finalize the chunk.
 
ssize_t qb_rb_chunk_peek (qb_ringbuffer_t *rb, void **data_out, int32_t ms_timeout)
 Read (without reclaiming) the last chunk.
 
void qb_rb_chunk_reclaim (qb_ringbuffer_t *rb)
 Reclaim the oldest chunk.
 
ssize_t qb_rb_chunk_read (qb_ringbuffer_t *rb, void *data_out, size_t len, int32_t ms_timeout)
 Read the oldest chunk into data_out.
 
int32_t qb_rb_refcount_get (qb_ringbuffer_t *rb)
 Get the reference count.
 
ssize_t qb_rb_space_free (qb_ringbuffer_t *rb)
 The amount of free space in the ring buffer.
 
ssize_t qb_rb_space_used (qb_ringbuffer_t *rb)
 The total amount of data in the buffer.
 
ssize_t qb_rb_chunks_used (qb_ringbuffer_t *rb)
 The total number of chunks in the buffer.
 
ssize_t qb_rb_write_to_file (qb_ringbuffer_t *rb, int32_t fd)
 Write the contents of the Ring Buffer to file.
 
qb_ringbuffer_tqb_rb_create_from_file (int32_t fd, uint32_t flags)
 Load the saved ring buffer from file into tempory memory.
 
int32_t qb_rb_chown (qb_ringbuffer_t *rb, uid_t owner, gid_t group)
 Like 'chown' it changes the owner and group of the ringbuffers resources.
 
int32_t qb_rb_chmod (qb_ringbuffer_t *rb, mode_t mode)
 Like 'chmod' it changes the mode of the ringbuffers resources.
 

Detailed Description

This implements a ring buffer that works in "chunks" not bytes.

So you write/read a complete chunk or not at all. There are two types of ring buffer normal and overwrite. Overwrite will reclaim the oldest chunks inorder to make way for new ones, the normal version will refuse to write a new chunk if the ring buffer is full.

This implementation is capable of working across processes, but one process must only write and the other prrocess read.

The read process will do the following:

for (i = 0; i < 200; i++) {
try_read_again:
l = qb_rb_chunk_read(rb, (void *)out, 32, 1000);
if (l < 0) {
goto try_read_again;
}
}
...
qb_rb_close(rb);

The write process will do the following:

rb = qb_rb_open("test2", 2000, QB_RB_FLAG_SHARED_PROCESS);
for (i = 0; i < 200; i++) {
try_write_again:
l = qb_rb_chunk_write(rb, &v, sizeof(v));
if (l < sizeof(v)) {
goto try_write_again;
}
}
...
Author
Angus Salkeld asalk.nosp@m.eld@.nosp@m.redha.nosp@m.t.co.nosp@m.m

Macro Definition Documentation

#define QB_RB_FLAG_CREATE   0x01

create a ring buffer (rather than open and existing one)

See Also
qb_rb_open()
#define QB_RB_FLAG_NO_SEMAPHORE   0x10

Don't use semaphores, only atomic ops.

This mean that the timeout passed into qb_rb_chunk_read() will be ignored.

#define QB_RB_FLAG_OVERWRITE   0x02

New calls to qb_rb_chunk_write() will call qb_rb_chunk_reclaim() if there is not enough space.

If this is not set then new writes will be refused.

See Also
qb_rb_open()
#define QB_RB_FLAG_SHARED_PROCESS   0x08

The ringbuffer will be shared between processes.

This effects the type of locks/semaphores that are used.

See Also
qb_rb_open()
#define QB_RB_FLAG_SHARED_THREAD   0x04

The ringbuffer will be shared between pthreads not processes.

This effects the type of locks/semaphores that are used.

See Also
qb_rb_open()

Typedef Documentation

typedef struct qb_ringbuffer_s qb_ringbuffer_t

Function Documentation

int32_t qb_rb_chmod ( qb_ringbuffer_t rb,
mode_t  mode 
)

Like 'chmod' it changes the mode of the ringbuffers resources.

Parameters
modemode to change to
rbringbuffer instance
Return values
0== ok
-errnofor error
int32_t qb_rb_chown ( qb_ringbuffer_t rb,
uid_t  owner,
gid_t  group 
)

Like 'chown' it changes the owner and group of the ringbuffers resources.

Parameters
owneruid of the owner to change to
groupgid of the group to change to
rbringbuffer instance
Returns
status (0 = ok, -errno for error)
void* qb_rb_chunk_alloc ( qb_ringbuffer_t rb,
size_t  len 
)

Allocate space for a chunk of the given size.

If type == QB_RB_FLAG_OVERWRITE then this will always return non-null but if it's type is QB_RB_NORMAL then when there is not enough space then it will return NULL.

Parameters
rbringbuffer instance
len(in) the size to allocate.
Returns
pointer to chunk to write to, or NULL (if no space).
See Also
qb_rb_chunk_alloc()
int32_t qb_rb_chunk_commit ( qb_ringbuffer_t rb,
size_t  len 
)

finalize the chunk.

Parameters
rbringbuffer instance
len(in) the size of the chunk.
ssize_t qb_rb_chunk_peek ( qb_ringbuffer_t rb,
void **  data_out,
int32_t  ms_timeout 
)

Read (without reclaiming) the last chunk.

This function is a way of accessing the next chunk without a memcpy(). You can read the chunk data in place.

Note
This function will not "pop" the chunk, you will need to call qb_rb_chunk_reclaim().
Parameters
rbringbuffer instance
data_out(out) a pointer to the next chunk to read (not copied).
ms_timeout(in) time to wait for new data.
Returns
the size of the chunk (0 if buffer empty).
ssize_t qb_rb_chunk_read ( qb_ringbuffer_t rb,
void *  data_out,
size_t  len,
int32_t  ms_timeout 
)

Read the oldest chunk into data_out.

This is the same as qb_rb_chunk_peek() memcpy() and qb_rb_chunk_reclaim().

Parameters
rbringbuffer instance
data_out(in/out) the chunk will be memcpy'ed into this.
len(in) the size of data_out.
ms_timeoutthe amount od time to wait for new data.
Returns
the size of the chunk, or error.
void qb_rb_chunk_reclaim ( qb_ringbuffer_t rb)

Reclaim the oldest chunk.

You will need to call this if using qb_rb_chunk_peek().

Parameters
rbringbuffer instance
ssize_t qb_rb_chunk_write ( qb_ringbuffer_t rb,
const void *  data,
size_t  len 
)

Write a chunk to the ring buffer.

This simply calls qb_rb_chunk_alloc() and then qb_rb_chunk_commit().

Parameters
rbringbuffer instance
data(in) the data to write
len(in) the size of the chunk.
Returns
the amount of bytes actually buffered (either len or -1).
See Also
qb_rb_chunk_alloc()
qb_rb_chunk_commit()
ssize_t qb_rb_chunks_used ( qb_ringbuffer_t rb)

The total number of chunks in the buffer.

Parameters
rbringbuffer instance
void qb_rb_close ( qb_ringbuffer_t rb)

Dereference the ringbuffer and if we are the last user destroy it.

All files, mmaped memory, semaphores and locks will be destroyed.

Parameters
rbringbuffer instance
qb_ringbuffer_t* qb_rb_create_from_file ( int32_t  fd,
uint32_t  flags 
)

Load the saved ring buffer from file into tempory memory.

Parameters
fdfile with saved ringbuffer data.
flagssame flags as passed into qb_rb_open()
Returns
new ringbuffer instance
See Also
qb_rb_write_to_file()
char* qb_rb_name_get ( qb_ringbuffer_t rb)

Get the name of the ringbuffer.

Parameters
rbringbuffer instance
Returns
name.
qb_ringbuffer_t* qb_rb_open ( const char *  name,
size_t  size,
uint32_t  flags,
size_t  shared_user_data_size 
)

Create the ring buffer with the given type.

This creates allocates a ring buffer in shared memory.

Parameters
namethe unique name of this ringbuffer.
sizethe requested size.
flagsor'ed flags
shared_user_data_sizesize for a shared data area.
Note
the actual size will be rounded up to the next page size.
Returns
a new ring buffer or NULL if there was a problem.
See Also
QB_RB_FLAG_CREATE, QB_RB_FLAG_OVERWRITE, QB_RB_FLAG_SHARED_THREAD, QB_RB_FLAG_SHARED_PROCESS
int32_t qb_rb_refcount_get ( qb_ringbuffer_t rb)

Get the reference count.

Parameters
rbringbuffer instance
Returns
the number of references
void* qb_rb_shared_user_data_get ( qb_ringbuffer_t rb)

Get a point to user shared data area.

Note
this is of size "shared_user_data_size" passed into qb_rb_open()
Parameters
rbringbuffer instance
Returns
pointer to shared data.
ssize_t qb_rb_space_free ( qb_ringbuffer_t rb)

The amount of free space in the ring buffer.

Note
Some of this space will be consumed by the chunk headers.
Parameters
rbringbuffer instance
ssize_t qb_rb_space_used ( qb_ringbuffer_t rb)

The total amount of data in the buffer.

Note
This includes the chunk headers (8 bytes per chunk).
Parameters
rbringbuffer instance
ssize_t qb_rb_write_to_file ( qb_ringbuffer_t rb,
int32_t  fd 
)

Write the contents of the Ring Buffer to file.

Parameters
fdopen file to write the ringbuffer data to.
rbringbuffer instance
See Also
qb_rb_create_from_file()