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, Fetch_SODB_Resource_t s_init );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, Fetch_SODB_Resource_t s_init ) { 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), (Fetch_SODB_Resource_t)init_fred ); return(fp); }