Although most of the time your resource manager will handle messages from
clients, there still could be times when you need to control the behavior
of the resource manager itself.
For example, if the resource manager is for a serial port, you'll likely
need a way to change the baud rate, and so on.
There are various ways you could send control information to a resource
manager:
- Stop the resource manager, and then restart it with new
command-line options.
This is an awkward method that leaves the device unavailable while the
resource manager is restarting.
It isn't a viable solution if the resource manager controls various
devices and you need to set different options (at different times)
for different devices.
- Accept write() messages that include control instructions.
This lets you control the resource manager from the command line or a
script; you can simply echo a command to a path that the
resource manager has registered.
However, the write() messages might be broken into smaller
messages, so your resource manager would have to be prepared to save the
pieces, reassemble them, and then act on them.
Your io_write handler also has to parse the commands, in
addition to handling write() messages from the clients.
- Send an IPC message, via
MsgSend(),
directly to the resource manager.
This message would contain a data structure that includes the control
instructions.
This method is fast, simple, and flexible, but it isn't portable because
MsgSend() isn't a POSIX function.
- Send control instructions via a
devctl()
command.
Such messages won't conflict with any other messages sent to the resource
manager, but this approach might not be portable because
devctl() isn't a POSIX function (it was in a draft standard,
but wasn't adopted).
See
"Handling devctl() messages,"
below.
- Set up a handler for "other" I/O messages when
you call
resmgr_attach().
As described in
"Initialize the resource manager attributes"
in the Bones of a Resource Manager chapter, you have to set the
RESMGR_FLAG_ATTACH_OTHERFUNC bit in the
flags member of the resmgr_attr_t structure,
and set the other_func member to point to the handler function.
However, as we mentioned earlier, we don't recommend this approach.
- Use
message_attach()
or
pulse_attach()
to attach a specified message range or pulse code for the dispatch handle.
When a message with a type in that range is received, the
dispatch_block() function calls the handler function that you
specify.
The message range must be outside the I/O range, and the messages or
pulses aren't associated with an OCB.
For more information, see
"Handling private messages and pulses,"
later in this chapter.
- Use an out-of-band I/O message, _IO_MSG.
This type of message is associated with an OCB, and is handled
through the resource manager's framework.
For more information, see
"Handling out-of-band (_IO_MSG) messages,"
later in this chapter.