Setting resource manager attributes

In addition to the structures that define the connect and I/O functions, you pass a resmgr_attr_t structure to resmgr_attach() to specify the attributes of the resource manager.

The resmgr_attr_t structure is defined as follows:

typedef struct _resmgr_attr {
    unsigned            flags;
    unsigned            nparts_max;
    size_t              msg_max_size;
    int                 (*other_func)(resmgr_context_t *,
                                      void *msg);
    unsigned            reserved[4];    
} resmgr_attr_t;

The members include:

flags
Lets you change the behavior of the resource manager interface. Set this to 0, or a combination of the following bits (defined in <sys/dispatch.h>):
  • RESMGR_FLAG_ATTACH_LOCAL — set up the resource manager, but don't register its path with procnto. You can send messages to the resource manager's channel (if you know where to find it).
  • RESMGR_FLAG_CROSS_ENDIAN — the server handles cross-endian support. The framework handles all necessary conversions on the server's side; the client doesn't have to do anything.

    If necessary, your resource manager can determine that a message came from a client of a different endian-ness by checking to see if the _NTO_MI_ENDIAN_DIFF bit is set in the flags member of the _msg_info structure that's included in the resmgr_context_t structure that's passed to the handler functions.

  • RESMGR_FLAG_NO_DEFAULT_FUNC — not implemented.
  • RESMGR_FLAG_RCM (QNX Neutrino 6.6 or later) — automatically adopt the client's resource constraint mode when handling a request.
Note: There are also some _RESMGR_FLAG_* bits (with a leading underscore), but you use them in the flags argument to resmgr_attach().
nparts_max
The number of components that should be allocated to the IOV array.
msg_max_size
The size of the message buffer.

These members will be important when you start writing your own handler functions.

If you specify a value of zero for nparts_max, the resource manager library will bump the value to the minimum usable by the library itself. Why would you want to set the size of the IOV array? As we'll see in the Getting the resource manager library to do the reply section of the Handling Read and Write Messages chapter, you can tell the resource manager library to do our replying for us. We may want to give it an IOV array that points to N buffers containing the reply data. But, since we'll ask the library to do the reply for us, we need to use its IOV array, which of course would need to be big enough to point to our N buffers.

other_func
Lets you specify a routine to call in cases where the resource manager gets an I/O message that it doesn't understand.
Note: In general, we don't recommend that you use this member. For private or custom messages, you should use _IO_DEVCTL or _IO_MSG handlers, as described in the Handling Other Messages chapter. If you want to receive pulses, use pulse_attach().

If the resource manager library gets an I/O message that it doesn't know how to handle, it'll call the routine specified by the other_func member, if non-NULL. (If it's NULL, the resource manager library will return an ENOSYS to the client, effectively stating that it doesn't know what this message means.)

You might specify a non-NULL value for other_func in the case where you've specified some form of custom messaging between clients and your resource manager, although the recommended approach for this is the devctl() function call (client) and the _IO_DEVCTL message handler (server) or a MsgSend*() function call (client) and the _IO_MSG message handler (server).

For non-I/O message types, you should use the message_attach() function, which attaches a message range for the dispatch handle. When a message with a type in that range is received, the dispatch_block() function calls a user-supplied function that's responsible for doing any specific work, such as replying to the client.