bpo_init provides the routines which attach and detach these segments and provides a way of registering resources allocated within the segments. The create routines provide the hints which are used with the functions described in the associated files.
void *Create_SODB_mmap_priv( const char *use_name,
const char *mmap_name,
size_t msize,
off_t moff,
int flags,
mode_t priv );
void *Create_SODB_shm_priv( const char *use_name,
const char *fname,
char id,
size_t msize,
int flags,
mode_t priv );
These functions create/attach the segments used by the other bpo_*
routines. They both return a pointer which is normally the base of
the mapped object (see note below about SODB_ADD_HEADER).
The functions take both take a use_name parameter which is the name by which this segment will be known. They also take a set of flags which are used to determine the properties of this segment (whether it supports dynamic allocation, etc), and a privileges parameter which determines the permissions on the segment. The other parameters are directly related to the system calls these functions overlay.
In the case of the _mmap function, the parameters are the file name to map, what offset into the file should be used, and how much of the file to map.
For the _shm function the parameters are the file name (which should exist) and the id to use in a call to the ftok() routine, and what the size of the shared memory segment should be.
There are two values that may be passed as the flag. These values are.
void *Create_SODB_mmap( const char *use_name,
const char *mmap_name,
size_t msize,
off_t moff,
int flags );
void *Create_SODB_shm( const char *use_name,
const char *fname,
char id,
size_t msize,
int flags );
These two routines are simply wrappers for the ones mentioned above,
but without the attache privileges parameter. These routines provide
default value for this parameter. The new defaults for both of the
privileges is 0600, which gives maximum security.
int Detach_SODB_mmap( void *hint );
int Detach_SODB_shm( void *hint );
There is also a call to use in case you do not know how a particular
SODB was attached.
int Detach_SODB_lump( const void *hint );
This will either detach (shmdt) the shared memory,
or munmap the relevant SODB.
void *Get_SODB_Pointer( const void *hint, off_t item_offset );
This function returns the pointer within the SODB of the hint for
the offset provided (or NULL if not supplied a valid hint for an SODB
or the offset if outside the supplied SODB).
off_t Get_SODB_Offset( const void *vp );
This function returns the offset into the SODB of the supplied
object (or 0 if not supplied a valid pointer for an SODB).
mode_t Get_SODB_Privs( const void *vp );
This function returns the attach mode of the SODB pointed to by the
parameter (or 0 if not supplied a valid pointer for an SODB).
void * Get_SODB_Base( const void *hint );
This function returns a pointer to the start of the SODB which
contains the hint (or NULL if the hint is not in an SODB).
int SODB_in_Segment( const void *hint, const void *chk );
This function returns a non-zero result if the check parameter is within
the same SODB as the hint.
These functions only work if the initial Create routine was called with SODB_USE_SHALLOC as part of the flags.
void * Find_SODB_Resource( void *hint, char *res_name );
The function returns a pointer to the named resource, it it exists.
If it does not, it returns a NULL. If a given resource is not found
it is likely that the following routine will be called.
off_t Add_SODB_Resource( void *object, char *res_name );
This adds a resource, with the supplied name, to the resource list
in the relevant segment. If the resource already exists, or there
is a problem in adding the resource (the segment does not support
resources) then the routine returns (off_t)0, otherwise it returns
the offset within the segment of the supplied object.
void * Fetch_SODB_Resource( void *hint, char *name, size_t s_size,
void (* s_init)( void * ) );
This function provides a wrapper for the Find_ and Add_ resource
functions. It is most easily described using the following
pseudo-code.
void * Fetch_SODB_Resource( void *hint, char *name, size_t s_size,
void (* s_init)( void * ) )
{
void *rv,tp;
rv = Find_SODB_Resource( hint, name );
if (rv==NULL)
{
tp = shalloc( hint, s_size );
if (tp)
{
(* s_init)( tp );
if (Add_SODB_Resource( tp, name )==(off_t)0)
shfree(tp);
rv = Find_SODB_Resource( hint, name );
}
}
return(rv);
}
As can be seen, we either find it, or create it. Note, we allow for
somebody creating it between our search and add. In addition, there
are a couple of other safety measures that are taken to ensure that
the memory cannot be freed by some rouge program.
The initialise function should perform any base initialisation required to the data area, but should not assume that the pointer passed is going to be the resource (given we may have been pre-empted).
For further clarification, consider the following code.
struct fred
{
struct bpo_pid_lock fred_lock;
int fred_value;
};
static void init_fred( struct fred *fp )
{
bpo_Init_pid_lock( &fp->fred_lock, NULL );
fp->fred_value=1;
return;
}
struct fred * find_fred( void *hint )
{
struct fred *fp;
fp = Fetch_SODB_Resource( hint, "FRED",
sizeof(struct fred),
(void (*)(void *))init_fred );
return(fp);
}