dispatch_create_channel()
Allocate a dispatch structure, specifying a channel ID
Synopsis:
#include <sys/iofunc.h>
#include <sys/dispatch.h>
dispatch_t *dispatch_create_channel( int chid,
unsigned flags );
Arguments:
- chid
- The ID of the channel to use for the dispatch layer, or -1 to create the channel.
- flags
- Zero or more of the following bits:
- DISPATCH_FLAG_NOLOCK — enable the lockless handling of messages (see below).
Library:
libc
Use the -l c option to qcc to link against this library. This library is usually included automatically.
Description:
The dispatch_create_channel() function allocates and initializes a dispatch structure, and returns a handle to this structure. This function is similar to dispatch_create() but lets you specify a channel and flags. This is useful if you want to control the channel for name_attach() or resmgr_attach(). For example, if you wanted two or more names to the same channel, or if you wanted non-default channel flags.
After you've called this function, you need to call one or more of the following functions to attach handlers for the things you want the dispatch layer to deal with:
Then you call dispatch_context_alloc() to allocate the context for dispatch_block() and dispatch_handler().
If the dispatch structure is for use in a resource manager, meaning you will later call resmgr_attach() with the associated dispatch handle, then at least the flags _NTO_CHF_UNBLOCK and _NTO_CHF_DISCONNECT should be set for the supplied channel to ensure proper resource manager behavior. If using select_attach() with the SELECT_FLAG_SRVEXCEPT, then _NTO_CHF_COID_DISCONNECT is also required.
If you wish, you can do a resmgr_attach() with a NULL path. This has the effect of initializing the dispatch structure to receive messages, among other things.
In most resource managers, the mapping from message types to message handlers is static for the life of the resource manager, but the lookup must be done on every message. The framework locks and unlocks the mapping data on every message, but if a resource manager is going to have a static mapping, this overhead can be eliminated. Setting the DISPATCH_FLAG_NOLOCK flag tells the dispatch framework that it can safely eliminate those protections. This means that once the dispatch framework becomes active (that is, once at least one call to dispatch_context_alloc() has been made with the dispatch framework), the mapping can't be changed. This has the restrictions that for an active dispatch framework (dpp) you may not call:
- message_attach()
- message_detach()
- pulse_attach()
- pulse_detach()
- resmgr_attach() unless at least one resmgr_attach() has been done before the dispatch_context_alloc()
- select_attach() unless at least one select_attach() has been done before the dispatch_context_alloc()
- select_attach() with the SELECT_FLAG_SRVEXCEPT flag unless at least one select_attach() with the SELECT_FLAG_SRVEXCEPT flag has been done before the dispatch_context_alloc()
The dispatch_create_channel() function is part of the dispatch layer of a resource manager.
For more information, see
Layers in a resource manager
in the The Bones of a Resource Manager
chapter of Writing a Resource Manager.
Returns:
A handle to a dispatch structure, or NULL if an error occurred (errno is set). The dispatch_t structure is an opaque data type; you can't access its contents directly.
Errors:
- EAGAIN
- One of the following occurred:
- The process can't allocate a new kernel channel object.
- The process exceeded its maximum allowed number of channels.
- The number of channels created by the process is greater than the limit specified for RLIMIT_CHANNELS_NP (see prlimit()).
- EINVAL
- The flags argument is invalid.
- ENOMEM
- Insufficient memory to allocate context.
- EPERM
- The process tried to create a public channel without having the required permission; see procmgr_ability().
Classification:
Safety: | |
---|---|
Cancellation point | No |
Signal handler | No |
Thread | Yes |