Component data access

The second issue associated with handling combine messages is how to access the data area for subsequent message components.

For example, the writeblock() combine message format has an lseek() message first, followed by the write() message. This means that the data associated with the write() request is further in the received message buffer than would be the case for just a simple _IO_WRITE message:

Client call:
writeblock()
Message(s):
_IO_LSEEK , _IO_WRITE , data
Callouts:
io_lock_ocb, io_lseek, io_write, io_unlock_ocb

This issue is easy to work around. There's a resource manager library function called resmgr_msgread() that knows how to get the data corresponding to the correct message component. Therefore, in the io_write handler, if you used resmgr_msgread() instead of MsgRead(), this would be transparent to you.

Note: Resource managers should always use resmgr_msg*() cover functions.

For reference, here's the source for resmgr_msgread():

ssize_t resmgr_msgread( resmgr_context_t * const ctp,
                        void * const msg,
                        const size_t size,
                        const size_t offset)
{
    return MsgRead(ctp->rcvid, msg, size, ctp->offset + offset);
}

As you can see, resmgr_msgread() simply calls MsgRead() with the offset of the component message from the beginning of the combine message buffer. For completeness, there's also a resmgr_msgwrite() that works in an identical manner to MsgWrite(), except that it dereferences the passed ctp to obtain the rcvid.