Extending the OCB
To extend the OCB, you'll need to provide two functions—one to allocate (and initialize) the new OCB and one to free it—to override the defaults, iofunc_ocb_calloc() and iofunc_ocb_free(). Then, you'll need to bind your two customized functions into the mount structure. (Yes, this does mean that you'll need a mount structure, if only for this one purpose.) Finally, you'll need to define your own OCB typedef, so that the prototypes for the code are all correct.
#define IOFUNC_OCB_T struct my_ocb
#include <sys/iofunc.h>
This tells the included file, <sys/iofunc.h>, that the manifest constant IOFUNC_OCB_T now points to your new and improved OCB structure.
normalOCB must appear as the first entry in your extended OCB! This is because the POSIX helper library passes around a pointer to what it expects is a normal OCB—it doesn't know about your extended OCB, so therefore the first data element at the pointer location must be the normal OCB.
typedef struct my_ocb
{
iofunc_ocb_t normal_ocb;
int my_extra_flags;
...
} my_ocb_t;
// declare
iofunc_mount_t mount;
iofunc_funcs_t mount_funcs;
// set up the mount functions structure
// with our allocate/deallocate functions
// _IOFUNC_NFUNCS is from the .h file
mount_funcs.nfuncs = _IOFUNC_NFUNCS;
// your new OCB allocator
mount_funcs.ocb_calloc = my_ocb_calloc;
// your new OCB deallocator
mount_funcs.ocb_free = my_ocb_free;
// set up the mount structure
iofunc_mount_init(&mount, sizeof(mount));
mount.conf |= IOFUNC_PC_ACL;
...
mount.funcs = &mount_funcs;
attr.mount = &mount;
IOFUNC_OCB_T * my_ocb_calloc (resmgr_context_t *ctp, IOFUNC_ATTR_T *attr);
void my_ocb_free (IOFUNC_OCB_T *ocb);
This means that the my_ocb_calloc() function gets passed both the internal resource manager context and the attributes structure. The function is responsible for returning an initialized OCB. The my_ocb_free() function gets passed the OCB and is responsible for releasing the storage for it.
There are two interesting uses for these two functions (that have nothing to do with extending the OCB):
- Monitoring the allocation and deallocation of OCBs
- In this case, you can simply
tie in
to the allocator/deallocator and monitor the usage of the OCBs (for example, you may wish to limit the total number of OCBs outstanding at any given time). This may prove to be a good idea if you're not taking over the open connect function handler, and yet still need to intercept the creation of (and possibly deletion of) OCBs. - Providing more efficient allocation and deallocation
- Another reason for overriding the library's built-in OCB allocator/deallocator is that you may wish to keep the OCBs on a free list, instead of using the library's calloc() and free() functions. If you're allocating and deallocating OCBs at a high rate, this may prove to be more efficient.