Now that we've covered the "basics" of resource managers, it's time to
look at some more complicated aspects.
Extending the OCB
In some cases, you may find the need to extend the OCB. This is relatively painless to do. The common uses for extending the
OCB are to add extra flags you wish to maintain on a per-open basis. One such flag could be used with the io_unblock() handler to cache the value of the kernel's _NTO_MI_UNBLOCK_REQ flag. (See the Message Passing chapter, under "Using the _NTO_MI_UNBLOCK_REQ" for more details.)
Extending the attributes structure
You may wish to extend the attributes structure in cases where you need to store additional device information. Since the
attributes structure is associated on a "per-device" basis, this means that any extra information you store there will be accessible to all OCBs that reference that device (since
the OCB contains a pointer to the attributes structure). Often things like serial baud rate, etc. are stored in extended attributes
structures.
Blocking within the resource manager
So far we've avoided talking about blocking within the resource manager. We assume that you will supply an outcall function
(e.g., a handler for io_read()), and that the data will be available immediately. What if you need to block, waiting for the data? For example, performing
a read() on the serial port might need to block until a character arrives. Obviously, we can't predict how long this will take.
Returning directory entries
In the example for the io_read() function above, we saw how to return data. As mentioned in the description of the io_read() function (in the "Alphabetical listing of Connect and I/O functions"), the io_read() function may return directory entries as well. Since this isn't something that everyone will want to do, I discuss it here.