Main Page   Data Structures   File List   Data Fields   Globals   Examples  

Shared Buffer Library libshbuf

0.0.3

Introduction

The shared buffers which libshbuf provides are intended to be a better IPC replacement for classic unix pipes. They offer the following advantages:

Technical overview

The library makes use of SYSV shared memory, semaphores an message queues. Additionaly it spawns a background thread using POSIX pthreads, alltough this is not shown in any way in the API.

Two shared memory blocks are created. One for control, which contains some information about the fill levels of the buffer, and one for the buffer itself. A semaphore is used for properly locking acces to the control block. A message queue is used for notifying changes to the other side of the buffer.

The library is not thread safe, but this should be easy to fix as no API changes are needed for accomplishing this.

Usage

(This part is a bit terse, I know. Just the most important things to know here.)

It is OK to manipulate the status block of the shared buffer directly. You can use shbuf_get_status() for getting a pointer to it. You are urged to lock access to the status block with shbuf_status_lock() and shbuf_status_unlock() when accessing it, for both writing and reading, or you will cause corruption.

Please note: Only the status block may be locked, not the buffer itself. This is a feature, not a bug. Locks should be kept for a minimal period of time. Thus only the status fields are secured with a mutual exclusion as their manipulation should take a very short timespan.

The functions shbuf_reset(), shbuf_zero(), shbuf_get_read_pointer(), shbuf_inc_read_pointer(), shbuf_get_write_pointer(), shbuf_inc_write_pointer(), shbuf_get_read_pointer(), shbuf_is_full(), shbuf_is_empty(), shbuf_read() are shbuf_write()() more or less simple shortcuts for some of the most often used accesses to the status block. Most of the time they should suffice for accessing the shared buffer.

Code Example

For an elaborate example see the source codes for shbuftest.c.

A shbuf client which writes data in a loop to the buffer should usually look like the following code excerpt:

    shbuf *sb;

    [...]
    
    // Open the shared buffer (some error checking for sb != 0 should follow.)
    sb = shbuf_open(4711);

    // Enable notifying mode (error checking...)
    shbuf_notify_enable(sb, 1);

    [...]

    // Do as long as there is still a server connected...
    while (shbuf_connected(sb) == 1) {
        unsigned char *p;
        unsigned long l;

        // Try to get a pointer to some available data
        if (!(p = shbuf_get_write_pointer(sb, &l))) {

             // No data available, we wait for a notification from
             // the provider. A select() on shbuf_get_select_fd(sb)
             // does nearly the same, but may listen on multiple
             // file descriptors.
             
             if (shbuf_wait(sb) < 0)
                 break;
           
             continue;
        }

      // Error check  
      if (p == (unsigned char*) -1)
           break;

      //  Now do some work on the l bytes referenced by p
      [...]
       
      // Tell the shared buffer, that we handled r bytes, which may be
      // removed from the buffer.
      if (shbuf_inc_write_pointer(sb, r) < 0)
          break;

      // Notify the other side about th changes 
      if (shbuf_notify(sb) < 0)
          break;
    } 

    // Cleanup
    shbuf_free(sb);

    [...]

Assorted Notes

System Independency

At the moment there is only a Linux tested version of this library available. It should be easy to port this library to any other system supporting SysV IPC and POSIX Pthreads. It should be even portable to operating systems with a completely different IPC or threading API: the relevant function calls in the library aren't visible through the API, so it should be easy to replace them through functionally equivalent system specific ones. Thus even MS Windows might be a target OS for this library.

Backlog

Since version 0.0.2 libshbuf features a facility I dubbed "backlog". It is sometimes needed for keeping some already read data in the buffer for being able to rewind to a specific position later. You may set the desired backlog size in bytes with shbuf_set_backlog_target(). The desired backlog size defaults to zero. The current backlog size may be queried with shbuf_rewind(). It may be smaller or larger than the desired target. You may call shbuf_rewind() for making use of the backlog.


Generated on Thu Sep 11 18:52:21 2003 for libshbuf by doxygen1.2.18