Defining a completion callback

A completion callback is defined as follows:

CS_RETCODE CS_PUBLIC completion_cb(connection, cmd,
                                   function,status)

CS_CONNECTION       *connection;
CS_COMMAND          *cmd;
CS_INT              function;
CS_RETCODE          status;

where:

A completion callback routine calls any Client-Library or CS-Library routine except cs_objects (CS_SET), ct_init, ct_exit, ct_setloginfo, and ct_getloginfo. cs_objects(CS_SET) is not asynchronous-safe, and ct_init, ct_exit, ct_setloginfo, and ct_getloginfo perform system-level memory allocation and deallocation.

If a completion callback calls an asynchronous Client-Library routine, it should return the value returned by the routine itself. Otherwise, there are no restrictions on what a completion callback can return. Sybase recommends, however, that the completion callback return CS_SUCCEED, if the completion callback succeeded, or CS_FAIL, if an error occurred.


Completion callback example

The following is an example of a completion callback. This code is from the Client-Library sample programs (file ex_alib.c):

           /*
           ** ex_acompletion_cb()
           **
           ** Type of function:
           **       example async lib
           **
           ** Purpose:
           **       Installed as a callback into Open Client. It 
           **       will dispatch to the appropriate completion
           **       processing routine based on async state.
           ** 
           **       Another approach to callback processing is to 
           **       have each completion routine install the 
           **       completion callback for the next step in 
           **       processing. We use one dispatch point to aid 
           **       in debugging the async processing (only need
           **       to set one breakpoint).
           **
           ** Returns:
           **       Return of completion processing routine.
           **
           ** Side Effects:
           **       None
           */
          CS_STATIC CS_RETCODE CS_PUBLIC
           ex_acompletion_cb(connection, cmd, function, status)
           CS_CONNECTION    *connection;
           CS_COMMAND       *cmd;
           CS_INT           function;
           CS_RETCODE       status;
           {
                CS_RETCODE  retstat;
                ExAsync     *ex_async;
               /*
                ** Extract the user area out of the command
                ** handle.
                */
                retstat = ct_cmd_props(cmd, CS_GET, CS_USERDATA,
                     &ex_async, CS_SIZEOF(ex_async), NULL);
                if (retstat != CS_SUCCEED)
                {
                     return retstat;
                }
               fprintf(stdout, "\nex_acompletion_cb: function \ 
                     %ld Completed", function);
               /* Based on async state, do the right thing */
                switch ((int)ex_async->state)
                {
                     case EX_ASEND:
                     case EX_ACANCEL_CURRENT:
                     retstat = ex_asend_comp(ex_async, connection,
                          cmd, function, status);
                     break;
                    case EX_ARESULTS:
                     retstat = ex_aresults_comp(ex_async,
                          connection, cmd, function, status);
                     break;
                    case EX_AFETCH:
                     retstat = ex_afetch_comp(ex_async,
                          connection, cmd, function, status);
                     break;
                    case EX_ACANCEL_ALL:
                     retstat = ex_adone_comp(ex_async, connection,
                          cmd, function, status);
                     break;
                    default:
                     ex_apanic("ex_acompletion_cb: unexpected \ 
                          async state");
                     break;
                }
               return retstat;
           }