z/OS Communications Server: IP Programmer's Guide and Reference
Previous topic | Next topic | Contents | Contact z/OS | Library | PDF


RAPI asynchronous event handling

z/OS Communications Server: IP Programmer's Guide and Reference
SC27-3659-02

The RAPI interface provides an asynchronous upcall mechanism using the select() function. The upcall mechanism is a cooperative effort between RAPI and the using application. The following shows the steps that must be taken by a RAPI application to receive asynchronous upcalls:
  1. The upcall function pointer must be specified on the rapi_session() call that initiates the RAPI session. If the upcall function requires an argument, that also must be specified on rapi_session(). The argument is defined as a pointer to void.
  2. The application must provide a means to be notified of asynchronous events. The best way to do this is to create a thread using pthread_create().
  3. The thread created above must issue the rapi_getfd() call to learn the file descriptor of the socket used by RAPI for asynchronous communication.
  4. The thread should then enter an endless loop to detect asynchronous events using the select() call with the file descriptor learned using rapi_getfd(). When an event is detected, the thread should call rapi_dispatch(), which then in turn calls the upcall function synchronously.
The following example illustrates these steps. This example is for illustration purposes only. It is not a complete program.
/*********************************************************************/ 
/* Issue a rapi_session() call to initialize RAPI.                   */ 
/*********************************************************************/ 
rapi_sid = rapi_session(&destination,                                   
                        protocol,                                       
                        0,                                              
                        rapi_async,   /* upcall function pointer     */ 
                        0,            /* no upcall argument          */ 
                        &rc);                                           
...
/*********************************************************************/ 
/* Create a pthread to handle RAPI upcalls.                          */ 
/*********************************************************************/ 
pthread_create(&thread_d,                                              
               NULL,                                                    
               &rapi_th,                                                
               NULL);                                                   
...
/*********************************************************************/ 
/* Function: rapi_th()                                               */ 
/*********************************************************************/ 
void *rapi_th(void *arg)                                                
{                                                                       
  fd_set      fds;                                                      
  int         fd;                                                       
  struct timeval tv;                                                    
                                                                        
  int               rc = SUCCESSFUL;                                    
                                                                        
  /*******************************************************************/ 
  /* This is the pthread created to handle RAPI upcalls.  First, get */ 
  /* the rapi socket descriptor to use on select().                  */ 
  /*******************************************************************/ 
  pthread_mutex_lock(&rapi_lock);                                       
  fd = rapi_getfd(rapi_sid);                                            
  pthread_mutex_unlock(&rapi_lock);                                     
                                                                        
  if (fd > 0) {                                                                                                                                 
    /*****************************************************************/ 
    /* Loop as long as all is well, waiting via select() for an      */ 
    /* asynchronous RAPI packet to arrive.                           */ 
    /*****************************************************************/ 
    while (rc == SUCCESSFUL) {                                          
      tv.tv_sec = 1;                                                    
      tv.tv_usec = 0;                                                   
                                                                        
      FD_ZERO(&fds);                                                    
      FD_SET(fd, &fds);                                                 
      switch(select(FD_SETSIZE, &fds, (fd_set *) NULL,                  
                    (fd_set *) NULL, &tv)) {                            
        /*************************************************************/ 
        /* Bad return from select().  Get out.                       */ 
        /*************************************************************/ 
        case -1:                                                        
          rc = UNSUCCESSFUL;                                            
          break;                                                      
        /*************************************************************/ 
        /* Time out on select().  Ignore.                            */ 
        /*************************************************************/ 
        case 0:                                                         
          break;                                                        
                                                                        
        /*************************************************************/ 
        /* Dispatch data have arrived.  Call the upcall function via */ 
        /* rapi_dispatch().                                          */ 
        /*************************************************************/ 
        default:                                                        
          pthread_mutex_lock(&rapi_lock);                               
          rc = rapi_dispatch();                                         
          pthread_mutex_unlock(&rapi_lock);                             
          break;                                                        
      }                                                                 
    }                                                                   
  }                                                                     
                                                                        
  /*******************************************************************/   
  /* Error on rapi_getfd().                                          */ 
  /*******************************************************************/ 
  else {                                                                
    rc = UNSUCCESSFUL;                                                  
  }                                                                     
                                                                        
  pthread_exit(NULL);                                                   
}                                                                       

Go to the previous page Go to the next page




Copyright IBM Corporation 1990, 2014