dispatch_create()

Updated: April 19, 2023

Allocate a dispatch structure and create the channel associated with it

Synopsis:

#include <sys/iofunc.h>
#include <sys/dispatch.h>

dispatch_t *dispatch_create( void );

Library:

libc

Use the -l c option to qcc to link against this library. This library is usually included automatically.

Description:

The dispatch_create() function allocates and initializes a dispatch structure, creates the channel associated with it, and returns a handle to the structure. It's a convenience cover function that's the equivalent of calling dispatch_create_channel( -1, 0 ). If you want to create the channel yourself (e.g., in order to use name_attach()), call dispatch_create_channel() instead of dispatch_create().

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().

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 structure. In QNX Neutrino 7.0 or later, these functions indicate an error of EINVAL if this happens.

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 and setting the maximum message size and number of message parts.

Note: This function creates a public channel (i.e., without _NTO_CHF_PRIVATE set), so your process must have the PROCMGR_AID_PUBLIC_CHANNEL ability enabled. For more information, see procmgr_ability().

The dispatch_create() 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:

ENOMEM
Insufficient memory to allocate context.
EPERM
The process tried to create a public channel without having the required permission; see procmgr_ability().

Examples:

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <fcntl.h>
#include <sys/iofunc.h>
#include <sys/dispatch.h>

int my_func( select_context_t *ctp, int fd,
             unsigned flags, void *handle ) {
   int   i, c;

   /* Do some useful stuff with data */
   i = read( fd, &c, 1 );
   fprintf( stderr, "activity on fd %d: read char %c,
                     return code %d\n", fd, c, i ); 
}

int main( int argc, char **argv ) {
   dispatch_t           *dpp;
   dispatch_context_t   *ctp;
   int                  fd, fd2;

   if( ( dpp = dispatch_create() ) == NULL ) {
     fprintf( stderr, "%s: Unable to allocate \
              dispatch handle.\n",argv[0] );
     return EXIT_FAILURE;
   }
    
   if( argc <= 2 || (fd = open( argv[1],
                    O_RDWR | O_NONBLOCK )) == -1 ) {
     return EXIT_FAILURE;
   }
   
   if( argc <= 2 || (fd2 = open( argv[2],
                    O_RDWR | O_NONBLOCK )) == -1 ) {
     return EXIT_FAILURE;
   }

   select_attach( dpp, NULL, fd,
      SELECT_FLAG_READ | SELECT_FLAG_REARM, my_func, NULL );
   select_attach( dpp, NULL, fd2,
      SELECT_FLAG_READ | SELECT_FLAG_REARM, my_func, NULL );
   ctp = dispatch_context_alloc( dpp );

   for(;;) {
     if( ctp = dispatch_block( ctp ) ) {
       dispatch_handler( ctp );
     }
   }
   return EXIT_SUCCESS;
}

For more examples using the dispatch interface, see message_attach(), resmgr_attach(), and thread_pool_create().

Classification:

QNX Neutrino

Safety:  
Cancellation point No
Interrupt handler No
Signal handler No
Thread Yes