Summary

Updated: April 19, 2023

Writing a resource manager is by far the most complicated task that we've discussed in this book.

A resource manager is a server that receives certain well-defined messages. These messages fall into two broad categories:

Connect messages
Related to pathname-based operations, these may establish a context for further work.
I/O messages
Always arrive after a connect message and indicate the actual work that the client wishes to have done (e.g., stat()).

The operations of the resource manager are controlled by the thread pool functions (discussed in the Processes and Threads chapter) and the dispatch interface functions.

QNX Neutrino provides a set of POSIX helper functions in the resource manager library that perform much of the work of dealing with the client's Connect and I/O messages that arrive.

There are a number of data structures relating to the clients and resources manifested by the resource manager to keep in mind:

OCB
Allocated on a per-open basis, this contains the context for the client (e.g., current lseek() position)
Attributes structure
Allocated on a per-resource basis, this contains information about the resource (e.g., size of the device, permissions)
Mount structure
Allocated on a per-resource-manager basis, and contains information about the characteristics of the entire resource manager.

The clients communicate with the resource manager via message passing by resolving the pathname (via the open() and other calls) into a node descriptor, process ID, channel ID, and handle.

Finally, you supply the functionality you wish to actually do in your resource manager, by overriding some of the callouts in the Connect and I/O functions table.