The library really does what we just talked about

Updated: April 19, 2023

By way of introduction to the library, let's see (briefly) what the calls do in the /dev/null resource manager.

dispatch_create_channel()
Creates a dispatch structure; this will be used for blocking on the message reception. There's a simpler function called dispatch_create(), but most resource managers should set DISPATCH_FLAG_NOLOCK in order to use a lockless message lookup (see the entry for dispatch_create_channel() in the C Library Reference for details).
iofunc_attr_init()
Initializes the attributes structure used by the device. We'll discuss attributes structures in more depth later, but for now, the short story is that there's one of these per device name, and they contain information about a particular device.
iofunc_func_init()
Initializes the two data structures cfuncs and ifuncs, which contain pointers to the connect and I/O functions, respectively. You might argue that this call has the most “magic” in it, as this is where the actual “worker” routines for handling all the messages got bound into a data structure. We didn't actually see any code to handle the connect message, or the I/O messages resulting from a client read() or stat() function call. That's because the library is supplying default POSIX versions of those functions for us, and it's the iofunc_func_init() function that binds those same default handler functions into the two supplied tables.
resmgr_attach()
Creates the channel that the resource manager will use for receiving messages, and talks to the process manager to tell it that we're going to be responsible for /dev/null.” While there are a lot of parameters, we'll see them all in painful detail later. For now, it's important to note that this is where the dispatch handle (dpp), pathname (the string /dev/null), and the connect (cfuncs) and I/O (ifuncs) message handlers all get bound together.
dispatch_context_alloc()
Allocates a dispatch internal context block. It contains information relevant to the message being processed.
Note: Once you've called dispatch_context_alloc(), don't call message_attach() or resmgr_attach() specifying a larger maximum message size or a larger number of message parts for the same dispatch handle. In QNX Neutrino 7.0 or later, these functions indicate an error of EINVAL if this happens. (This doesn't apply to pulse_attach() or select_attach() because you can't specify the sizes with these functions.)
dispatch_block()
This is the dispatch layer's blocking call; it's where we wait for a message to arrive from a client.
dispatch_handler()
Once the message arrives from the client, this function is called to process it.