EPI call synchronization types

The EPI C++ classes support synchronous ("blocking"), and deferred synchronous ("polling") and asynchronous ("callback") protocols.

In the example above the CclSession object is created with the synchronization type of Ccl::sync. When this CclSession object is passed as the first parameter on a CclTerminal send method, a synchronous call is made to CICS®. The C++ Client application is then blocked until the reply was received from CICS. When the reply is received, updates are made to the CclScreen object according to the 3270 data stream received, then control is returned to the C++ program.

To make asynchronous calls the CclSession object used on the CclTerminal send method is created with a synchronization type of Ccl::async. The call is made to CICS using the CclTerminal send method, but control returns immediately to the Client application without waiting for a reply from CICS. The CclTerminal object starts a separate thread which waits for the reply from CICS. When a reply is received, the handleReply method on the CclSession object is invoked. To process the reply, the handleReply method should be overridden in a CclSession subclass:

  class MySession : public CclSession {
  public:
      MySession(Ccl::Sync protocol) : CclSession( protocol ) {}
      // Override reply handler method
      void handleReply( State state, CclScreen* screen );
  };

The implementation of the handleReply method can process the screen data available in the CclScreen object, which will have been updated in line with the 3270 data stream sent from CICS:

  void MySession::handleReply( State state, CclScreen* screen ) {
      // Check the state of the session
      switch( state ) {
      case CclSession::client:
      case CclSession::idle:
          // Output data from the screen
          for ( int i=1; i < screen->fieldCount(); i++ ) {
              cout << "Field " << i << ": " << screen->field->text();
          screen->setAID( CclScreen::PF3 );
          …
      } // end switch
  }

The handleReply method is called for each transmission received from CICS. Depending on the design of the CICS server program, a CclTerminal send call may result in one or more replies. The state parameter on the handleReply method indicates whether the server has finished sending replies:
CclSession::server
indicates that the CICS server program is still running and has further data to send. The Client application can process the current screen contents immediately, or simply wait for further replies.
CclSession::client
indicates that the CICS server program is now waiting for a response. The Client application should process the screen contents and send a reply.
CclSession::idle
indicates that the CICS server program has completed. The Client application should process the screen contents and either disconnect the terminal, or start a further transaction.

Most Client application will want to wait until the CICS server program has finished sending data (that is, the CclSession/CclTerminal state is client or idle) before processing the screen. However, some long-running server programs may send intermediate results or progress information that can usefully be accessed while the state is still server.

The implementation of the handleReply method can read and process data from the CclScreen object, update fields as required, and set the cursor position and AID key in preparation for the return transmission to CICS. The Client application main program should invoke further methods (send or disconnect) on the CclTerminal object to drive the server application:
  try {
      // Connect to CICS server
      CclTerminal terminal( "CICS1234" );
      // Create asynchronous session
      MySession session(Ccl::async);
      // Start CESN transaction on CICS server
      terminal.send( &session, "CESN" );
      // Replies processed asynchronously in overridden
      // handleReply method
      …
  } catch ( CclException &exception ) {
      cout << "CclClass exception: " << exception.diagnose() << endl;
  }

Note that the handleReply method is run on a separate thread. If the main Client application program needs to know when the reply has been received, a message or semaphore could be used to communicate between the handleReply method and the main program.

To make deferred synchronous calls the CclSession object used on the CclTerminal send method is created with a synchronization type of Ccl::dsync. As in the asynchronous case, a call is made to CICS using the CclTerminal send method and control returns immediately to the Client application without waiting for a reply from CICS. 3270 screen updates from CICS must be retrieved later using the poll() method on the Terminal object:
  try {
      // Connect to CICS server
      CclTerminal terminal( "CICS1234" );
      // Create deferred synchronous session
      MySession session(Ccl::dsync);
      // Start CESN transaction on CICS server
      terminal.send( &session, "CESN" );
      …
      if ( terminal.poll())
          // reply processed in handleReply method
      else
          // no reply received yet
  } catch ( CclException &exception ) {
      cout << "CclClass exception: " << exception.diagnose() << endl;
  }

A CICS server transaction may send more than one reply in response to a CclTerminal send call. More than one CclTerminal poll call may therefore be needed to collect all the replies. Use the CclTerminal state method to find out if further replies are expected. If there are, the value returned will be server.

As in the synchronous and asynchronous cases, the handleReply method can conveniently be used to encapsulate the code processing the 3270 data returned from CICS from one or more transmissions.