Solstice Enterprise Manager 4.1 Developing C++ Applications Doc Set ContentsPreviousNextIndex


Chapter 8

Performing Asynchronous Management Operations

A management operation can take a significant length of time to finish, particularly if the operation exchanges a large quantity of data between your application and the network resources it is managing. If your application is blocked while waiting for an operation to finish, the application may appear unresponsive to a user, or may fail to respond quickly enough to important events on your network. Performing asynchronous management operations enables an application to continue with other processing without waiting for the operations to finish.

This chapter explains how to enable applications to perform asynchronous management operations.

8.1 Asynchronous and Synchronous Operation

Your application can perform a management operation in synchronous or asynchronous mode.

In synchronous mode, all functions within the application wait until the operation is complete before returning. In this way, the thread of control is blocked after a function is called, and the application can make use of the result immediately after the function returns.

In asynchronous mode an application can initiate several concurrent asynchronous operations before receiving any of the results. The results are not guaranteed to be returned in any particular order. Asynchronous mode enables an application to continue with other processing without waiting for a function to return, but does not enable the result to be used immediately.


Note – Despite the similarities in terminology, these modes are not related to synchronization.

8.2 Specifying Asynchronous Operations

To enable an application to continue processing while the application is waiting for the result of an operation, call the asynchronous function for the operation. Calling an asynchronous function initiates an operation, but returns program control to your application before the operation finishes.

In the call to an asynchronous function, you can optionally specify a callback function to be run when the asynchronous operation finishes. For more information, see Section 8.3 Handling Responses From an Asynchronous Operation.

An asynchronous function returns an instance of the Waiter class. The function does not return the result of the operation initiated. The Waiter class represents an unfinished asynchronous operation. The instance of Waiter returned enables you to:

You can choose to perform the following types of operations asynchronously:

In addition, the Album class provides functions for performing asynchronous CMIS operations on object collections.

8.2.1 Interactions With the MIS

The Platform class provides functions for synchronously or asynchronously interacting with the MIS. The names of asynchronous functions are prefixed with start. To specify whether your application interacts with the MIS synchronously or asynchronously, call the appropriate version of the function as listed in TABLE 8-1.

TABLE 8-1   Synchronous and Asynchronous Functions of the Platform Class 
Operation Synchronous Asynchronous
Connect an application to the MIS
connect
start_connect
Disconnect an application from the MIS
disconnect
start_disconnect


8.2.2 Asynchronous Operations on Managed Objects

For each management operation that you can perform on a managed object, the Image class provides a function for performing it synchronously or asynchronously. The names of asynchronous functions are prefixed with start. To specify whether a management operation is performed synchronously or asynchronously, call the appropriate version of the function as listed in TABLE 8-2.

TABLE 8-2   Synchronous and Asynchronous Functions of the Image Class 
Operation Synchronous Asynchronous
Activate or update an instance of Image
boot
start_boot
Deactivate an instance of Image
shutdown
start_shutdown
Update attribute values in the MIS
store
start_store
Add a managed object to the MIS
create
start_create
Add, in containing object, a managed object to the MIS
create_within
start_create_within
Remove a managed object from the MIS
destroy
start_destroy
Send an action request with a text parameter
call
start
Send an action request with an encoded parameter
call_raw
start_raw


8.2.3 Asynchronous Operations on Object Collections

For each management operation that you can perform on an object collection, the Album class provides a function for performing it synchronously or asynchronously. The names of asynchronous functions contain the text start. To specify whether a management operation is performed synchronously or asynchronously, call the appropriate version of the function as listed in TABLE 8-3.

TABLE 8-3   Synchronous and Asynchronous Functions of the Album Class 
Operation Synchronous Asynchronous
Define the membership of an object collection
derive
start_derive
Activate all Image instances in an object collection
all_boot
all_start_boot
Deactivate all Image instances in an object collection
all_shutdown
all_start_shutdown
Update attribute values in the MIS for all Image instances in an object collection
all_store
all_start_store
Add all managed objects in an object collection to the MIS
all_create
all_start_create
Add, in a containing object, all managed objects in an object collection to the MIS
all_create_within
all_start_create_within
Remove all managed objects in an object collection from the MIS
all_destroy
all_start_destroy
Send an action request with a text parameter to all managed objects in an object collection
all_call
all_start
Send an action request with an encoded parameter to all managed objects in an object collection
-
all_start_raw



Note – The Album class does not provide a function for sending an encoded synchronous action request to an object collection.

8.2.4 Asynchronous CMIS Operations on Object Collections

The Album class provides functions for performing asynchronous management operations defined by the common management information service (CMIS). CMIS is specified in recommendation ITU-T X.710/ISO-9595 Common Management Information Services (CMISE). Use these functions if you want to perform an operation on a subset of the managed objects in an object collection.

You can perform asynchronous management operations on an object collection only if all of the following conditions are met:

The Album class provides functions for performing the CMIS operations listed in TABLE 8-4. For a definition of all CMIS operations, refer to ITU-T X.710/ISO-9595 Common Management Information Services (CMISE).

TABLE 8-4   CMIS Operations Supported by the Album Class 
Operation Definition
M-DELETE
Deletes a managed object
M-GET
Obtains attribute values from a managed object
M-SET
Modifies attribute values for a managed object
M-ACTION
Performs an action on a managed object


Performing an asynchronous CMIS operation on an object collection involves:

8.2.4.1 Selecting the Managed Objects to be the Subject of a CMIS Operation

The derivation string of the Album instance that contains an object collection selects the managed objects that are the subject of a CMIS operation on the object collection.

If you want to select all managed objects in an object collection, leave the derivation string unchanged after you call the derive function of the Album class.

If you want to select a subset of the managed objects in an object collection, reset the derivation string but do not call the derive function of the Album class.

Code for selecting the managed objects to be the subject of a CMIS operation is shown in CODE EXAMPLE 8-1.

CODE EXAMPLE 8-1   Selecting Managed Objects for a CMIS Operation 
...
#include <pmi/hi.hh>           // High Level PMI
...
Album nologs_album = Album("All objects except log objects"); 
...
// Set derivation string for populating the object collection 
// and then start the derivation
DU ALL_OBJECTS_EXCEPT_LOG = 
    "ALL/CMISFilter(not:{item:equality:{objectClass,log}})";
if (!nologs_album.set_derivation(ALL_OBJECTS_EXCEPT_LOG)) {
    cout << nologs_album.get_error_string() << endl;
    exit(3);
}
if (!nologs_album.derive()) {
    cout << nologs_album.get_error_string() << endl;
    exit(4);
}
...
// Reset the derivation string to select objects for CMIS operation,
// but do not start a derivation
DU ALL_SECOND_LEVEL_OBJECTS_EXCEPT_LOG = 
    "LV(2)/CMISFilter(not:{item:equality:{objectClass,log}})";
if (!nologs_album.set_derivation(ALL_SECOND_LEVEL_OBJECTS_EXCEPT_LOG)) {
    cout << nologs_album.get_error_string() << endl;
    exit(5);
}
...

In this example, an object collection containing all managed objects except instances of the log class is created. After the membership of this object collection has been defined by derivation, the derivation string is reset to select all second-level subordinates of the system object except instances of the log class. To preserve the membership of the object collection, the derive function of the Album class is not called after the derivation string is reset.

8.2.4.2 Requesting a CMIS Operation

When you have selected the objects to be the subject of a CMIS operation, call one of the functions listed in TABLE 8-5 to request the operation. Additional information on how to call each function listed in TABLE 8-5 is given in the following subsections.

TABLE 8-5   Functions of the Album Class for Requesting CMIS Operations 
Operation Function
M-GET
start_m_get
M-SET
start_m_set
M-ACTION with a text parameter
start_m_action
M-ACTION with an encoded parameter
start_m_action_raw
M-DELETE
start_m_delete


Requesting an Asynchronous CMIS M-GET Operation

To request an asynchronous CMIS M-GET operation, call the start_m_get function of the Album class.

In the call to start_m_get, specify:

Requesting an Asynchronous CMIS M-SET Operation

To request an asynchronous CMIS M-SET operation, call the start_m_set function of the Album class.

In the call to start_m_set, specify:

To specify a modification list, create a queue of AttrModifier instances and pass this queue to start_m_set. The AttrModifer class represents a single modification to an attribute of a managed object.

Creating a queue of AttrModifier instances involves:

In the call to the constructor of the AttrModifier class, specify the name of the attribute you want to set.

To specify how you want to set the attribute, call functions of the AttrModifier class as follows:

TABLE 8-6   Operations for the set_operator Function 
Operation Result
REPLACE
Replaces the existing value with that specified in the function call. It corresponds to the REPLACE operation in a property list. This is the default operation.
ADD
Adds the value specified in the function call to the current value of a multi-valued attribute. It corresponds to the ADD operation in a property list. Specify the ADD operation for multi-valued attributes only. If you specify the ADD operation for a single-valued attribute, an exception is thrown.
REMOVE
Removes the value specified in the function call from the current value of a multi-valued attribute. It corresponds to the REMOVE operation in a property list. Specify the REMOVE operation for multi-valued attributes only. If you specify the REMOVE operation for a single-valued attribute, an exception is thrown.
SET_TO_DEFAULT
Replaces the existing value with the default value defined in the property list in the ATTRIBUTES construct of the attribute's GDMO specification.


Code for requesting an asynchronous CMIS M-SET operation is shown in CODE EXAMPLE 8-2.

CODE EXAMPLE 8-2   Requesting an Asynchronous CMIS M-SET Operation 
...
#include <pmi/hi.hh>           // High Level PMI
#include <queue.hh>            // Queue class declaration
...
Album nologs_album = Album("All objects except log objects"); 
...
Queue (AttrModifier) amq;
Morf val;
AttrModifier * elt1 = new AttrModifier (CDU coordinates);
elt1->set_operator (REPLACE);
elt1->set_value (&val);
amq.enq (elt1);
AttrModifier * elt2 = new AttrModifier (CDU highWaterMark);
elt2->set_operator (SET_TO_DEFAULT);
amq.enq (elt2);
nologs_album.start_m_set (amq);
...

In this example, a queue named amq of AttrModifier instances is created. The AttrModifier instances in the queue specify that:

Requesting an Asynchronous CMIS M-ACTION Operation With a Text Parameter

To request an asynchronous CMIS M-ACTION operation with a text parameter, call the start_m_action function of the Album class.

In the call to start_m_action, specify:

Requesting an Asynchronous CMIS M-ACTION Operation With an Encoded Parameter

To request an asynchronous CMIS M-ACTION operation with an encoded parameter, call the start_m_action_raw function of the Album class.

In the call to start_m_action_raw, specify:

Requesting an Asynchronous CMIS M-DELETE Operation

To request an asynchronous CMIS M-DELETE operation, call the start_m_delete function of the Album class. In the call to start_m_delete, specify a callback function to be called when the management operation is complete.

8.3 Handling Responses From an Asynchronous Operation

An application receives the following types of responses from an asynchronous operation:

Handling responses to asynchronous operations involves:

8.3.1 Registering a Callback Function for the Completion of an Asynchronous Operation

Register a callback to specify the processing that is carried out when an asynchronous operation finishes. Registering a callback associates the callback with an asynchronous operation. The callback is run when your application receives a confirmation that the asynchronous operation has finished.

Registering a callback function for the completion of an asynchronous operation is optional. By default, no callback is registered when you call a function for performing an asynchronous operation.

To register a callback, pass it as a parameter to the asynchronous function. In the asynchronous function call, initialize an instance of the Callback class to represent the callback function.

To initialize an instance of the Callback class, call its constructor in the asynchronous function call. In the call to the constructor of the Callback class, you must specify:

Code for registering a callback for an asynchronous operation is shown in CODE EXAMPLE 8-3.

CODE EXAMPLE 8-3   Registering a Callback for an Asynchronous Operation
...
#include <pmi/hi.hh>           // High Level PMI
...
Waiter alb_waiter = myAlbum.start_derive( 
    Callback(alb_derived_cb, (Ptr)&cb_info));
...

In this example, the start_derive function of the Album class is called to start the derivation of an Album instance asynchronously. The callback function alb_derived_cb is registered so that it is called when the derivation finishes. A pointer to data contained in the cb_info object is passed to the callback function.

8.3.2 Registering a Callback Function for Handling Responses From Managed Objects

The callback registered in the call to a function for an asynchronous operation is called only once, when the operation is completed. To handle responses from managed objects to an asynchronous function call, you must register a callback specifically for that purpose.

To register a callback for handling responses from managed objects, call the when_resp function on the Waiter instance returned by the asynchronous function call.

In the call to when_resp, specify the callback function for handling responses from managed objects. This callback function is called each time your application receives a response to the asynchronous operation that returned the Waiter instance on which when_resp is called.

Code for registering a callback function to handle responses from managed objects is shown in CODE EXAMPLE 8-4.

CODE EXAMPLE 8-4   Registering a Callback Function for Response Handling 
...
#include <pmi/hi.hh>           // High Level PMI
...
Waiter cur;
...
if (!(cur=test_album.all_start(DU("topoGetNodeReport"),
  DU("NULL"),Callback(done_cb, &done)))) {
    cout << 
test_album.get_error_string() << endl;
    exit(9);
}
if (cur.get_except()) {
    cout << cur.get_except()->reason() << endl;
    exit(10);
}
// subscribe to any future incoming replies
 cur.when_resp(Callback(asyn_cb,0));
...

In this example, the all_start function of the Album class is called to send an asynchronous action request with a text parameter to all managed objects in an object collection. The when_resp function is called on the Waiter instance returned by the call to all_start. The call to when_resp registers a callback function named asyn_cb. The asyn_cb function is called each time the application receives a response to the asynchronous action from a managed object.

8.3.3 Writing Callback Functions for Asynchronous Operations

Write a callback function to handle each type of asynchronous operation and response you want to process. Each callback function you write must contain the code needed to carry out the processing you require. Writing a callback function involves:

8.3.3.1 Defining the Signature of the Callback Function

The signature of any callback function you write must be in the following format:

void callbackName (Ptr 
userdata, Ptr calldata)

Where:

8.3.3.2 Writing Code for Handling a Confirmation That an Asynchronous Operation Has Finished

In the body of your callback function, provide code that you want your application to run when an asynchronous operation finishes. The code you write depends on what you want the callback to do when it is run. If you do not need to process the data that the scheduler passes to the callback function, you can ignore callback's second argument.

An example of a callback for processing a confirmation that an asynchronous operation has finished is given in CODE EXAMPLE 8-5.

CODE EXAMPLE 8-5   Callback for Completion of an Asynchronous Operation 
...
#include <pmi/hi.hh>            // High Level PMI 
...
void alb_derived_cb(Ptr context_data, Ptr)
{
    callback_data *cb_data = (callback_data *)context_data;
    char **args_list = cb_data->get_args();
    char *g_class = cb_data->get_derivation_class();
    fprintf(stdout,
    "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    fprintf(stdout,
        "%s: Album Derivation Callback Function\n",
        args_list[0]);
    Album alb = cb_data->get_album();
    if (!alb)
        fprintf(stderr,
            "%s: Error initializing Album in callback\n",
            args_list[0]);
    else {
        fprintf(
stdout,
            "Number of %s instances found: %d\n",
            g_class, alb.num_images());
    }
    fprintf(stdout,
    "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    delete cb_data;
    fprintf(stdout,
        "\n%s: Program complete, terminating MIS connection\n\n", args_list[0]);
    MIS_Connected = FALSE;
}

When this callback is run, it checks for the success of the derivation. If the derivation fails, the callback prints a message stating that the derivation has failed. If the derivation succeeds, the callback prints the number of Image instances in the derived Album instance.

8.3.3.3 Writing Code for Handling Responses From Managed Objects

In the body of your callback function, provide code that you want your application to run when it receives a response from a managed object. The code you write depends on what you want the callback to do when it is run.

Making Correct Use of the Data Passed By the Scheduler

If you intend to register your callback by calling when_resp, you must use the data that the scheduler passes to the callback function to build a CurrentEvent object. This data is a void pointer. It is passed in the second argument of the callback.

If you ignore this data, memory allocated by the scheduler for this data is not freed, leading to a memory leak.

Code that correctly uses the data passed by the scheduler is shown in CODE EXAMPLE 8-6.

CODE EXAMPLE 8-6   Correct Use of Data Passed by the Scheduler 
...
void cb(Ptr userdata, Ptr calldata)
{
// do whatever
if(calldata)
        {
        CurrentEvent ce(calldata);
        //     Do whatever and use and access the information 
        //        within the CurrentEvent ce
        }
// do whatever
}
...

In this example, the data passed by the scheduler is used in the callback to build a CurrentEvent object. The memory allocated by the scheduler for this data is freed, thereby avoiding a memory leak.

Code that does not correctly use the data passed by the scheduler is shown inCODE EXAMPLE 8-7.

CODE EXAMPLE 8-7   Incorrect Use of Data Passed by the Scheduler 
...
void cb(Ptr userdata,Ptr calldata)
{
// do whatever but never use calldata to build
// a CurrentEvent object.
}
// or
void cb(Ptr userdata)
{
// do whatever and ignore the second argument
}
...

In this example, the data passed by the scheduler is ignored, leading to a memory leak.

Extracting Information Contained In a Response From a Managed Object

Extract the information contained in responses that is useful to the user of your application. To extract information contained in a response, call functions of the CurrentEvent class in the body of your callback function.

The information available depends on the response.

Information available from all responses and the functions for extracting the information are given in TABLE 8-7.

TABLE 8-7   Information Available From All Responses 
Information Function
A pointer to the response that caused the callback function to be called. This pointer has no meaning outside the scope of the CurrentEvent object that represents the response.
get_message
The Album instance associated with the response.
get_album
The Image instance associated with the response.
get_image
The class of the managed object that sent the response.
get_objclass
The fully distinguished name (FDN) of the managed object that sent the response.
get_objname


Information available only from action replies sent in response to CMIS M-ACTION requests and the functions for extracting the information are given in TABLE 8-8.

TABLE 8-8   Information Available Only From Action Replies 
Information Function
The action reply information in encoded form.
get_info_raw
The name of the action request.
get_eventtype



Note – The information available from responses is a subset of the information available from event notifications. Functions of the CurrentEvent class that are not listed in TABLE 8-7 and TABLE 8-8 extract meaningful information only from event notifications, not from responses. For more information, refer to Section 7.2.2.2 Extracting Information From an Event Notification.

Example Callback for Handling Responses From Managed Objects

A callback function for handling responses from managed objects is shown in CODE EXAMPLE 8-8.

CODE EXAMPLE 8-8   Callback for Handling Responses From Managed Objects 
...
#include <pmi/hi.hh>            // High Level PMI 
...
void asyn_cb( Ptr , Ptr calldata)
{
static int num = 1;
        cout << "\nExecuting asyn1 callback function for ";
    cout << num << " times";
        cout << endl;
    cout << "----------------------------------------------" << endl;
    num++;
        // Get and print the new attribute value.
        cout << "During the all_start operation ";
        cout << endl;
if(calldata)
    {
        CurrentEvent ce(calldata);
        cout << "OBJNAME = " << ce.get_objname().chp() << endl;
        cout << "OBJCLASS = " << ce.get_objclass().chp() << endl;
        MessagePtr msg = (MessagePtr)ce.get_message();
    if(msg->type()==ACTION_RES)
    {
    ActionRes* srmsg = (ActionRes*)msg;
    cout << "OBJCLASS = " << oc2name(srmsg->oc).chp() << endl;
    cout << "FDN = " << oi2fdn(srmsg->oi).chp() << endl;
    cout << "ACTION-TYPE = " << endl;
    (srmsg->action_type).print(stdout);
    cout << "\n" << endl;
    cout << "ACTION-REPLY = " << endl;
    (srmsg->action_reply).print(stdout);
    cout << "\n" << endl;
    }
        Morf mf = ce.get_info_raw();
        Asn1Value val = mf.get_value();
        if(val)
        {
        cout << "info_raw() field of current event ACTION-REPLY = " << endl;
        val.print(stdout);
        cout << "\n" << endl;
        }
    cout << "eventtype() field of current event ACTION-TYPE = " << 
    ce.get_eventtype().chp() << endl;
        cout << "Information setting in the current event related Album " << endl;
        cout << "Derivation rule for the Album " << 
        ce.get_album().get_prop(duNICKNAME).chp() << " is : " << 
        ce.get_album().get_derivation().chp() << endl;
        cout << "\n" << endl;
        cout << "Information setting in the current event related Image" << endl;
        Image im = ce.get_image();
        cout << " image name is " << im.get_objname().chp() << endl;
        cout << " image class is " << im.get_objclass().chp() << endl;
        cout << " image state is " << im.get_state().chp() << endl;
        cout << " image last_error is " << im.get_last_error().chp() << endl;
        if (im.exists())
        cout << " image exists " << endl;
        else
        cout << " image does not exist " << endl;
    cout << " attribute(s) and attribute value(s) setting in the image " << endl;
        Array(DU) attr_names = im.get_attr_names();
        for (int i=0; i<attr_names.size; i++) {
                char *name = strdup(attr_names[i].chp());
                cout << name;
                cout << ":  ";
                cout << im.get_str(name).chp() << endl;
        }
        cout << "\n" << endl;
    }
}

The callback in this example checks a response to determine if the response is an action reply. If the response is an action reply, the following information about the action reply are printed:

For any response, the callback then prints out the following information:

8.3.4 Scheduling Response Handling

An application cannot predict when it will receive a response to an asynchronous operation. Therefore, to process a response to an asynchronous operation, an application must be able to interrupt whatever function is being performed and process the response when it is received. To interrupt the function it is currently performing, an application requires a scheduler. A scheduler retrieves each event from the event queue and calls the function required to process the event correctly.

To schedule response handling, use one of the schedulers that Solstice EM provides:

Use these schedulers for response handling in the same way that you use them for event handling as explained in:

When you use the sched scheduler for response handling, you can schedule response handling in either of the following modes, depending on the requirements of your application:

When you use the xtsched scheduler for response handling, you can schedule response handling in nonblocking mode only.

8.3.4.1 Scheduling Response Handling in Nonblocking Mode

In nonblocking mode, your application continues with other operations while an asynchronous is outstanding.

To schedule response handling in nonblocking mode, activate the scheduler in a loop as shown in CODE EXAMPLE 8-9.

CODE EXAMPLE 8-9   Scheduling Nonblocking Asynchronous Response Handling 
...
#include <pmi/hi.hh>           // High Level PMI
...
// Non-Blocking Example (note: boot_cb not shown in this example):
        Waiter waiter1 = cell_image.start_create(Callback(boot_cb, 0));
        waiter1.waitmore(3.0); // Specify 3 sec. timeout for boot operation
        while (MIS_Connected)
            dispatch_recursive(TRUE);
...

In this example, the dispatch_recursive function of the sched scheduler is called while the application remains connected to an MIS.

8.3.4.2 Scheduling Response Handling in Blocking Mode

In blocking mode, your application carries out some operations only after an asynchronous operation has finished. Blocking mode enables your application to carry out other operations while the asynchronous operation is outstanding.

To schedule response handling in blocking mode, activate the scheduler in a loop only while the asynchronous operation is still outstanding. To test whether the asynchronous operation is still outstanding, call the was_completed function of the Waiter class repeatedly until it returns a value indicating that the operation represented by the Waiter instance has finished.

Outside the loop, call functions for operations that you want to be carried out only after the asynchronous operation has finished.

Inside the loop, call functions for operations you want to be carried out while the asynchronous operation is outstanding. These operations must not block the application.

Code for scheduling response handling in blocking mode is shown in CODE EXAMPLE 8-10.

CODE EXAMPLE 8-10   Scheduling Blocking Asynchronous Response Handling 
...
#include <pmi/hi.hh>     // High Level PMI
...
// Blocking Example:
        Waiter waiter2 = cell_album.all_start_store();
        while (!waiter2.was_completed){
        // Do operations you want to be carried out while the 
        // asynchronous operation is outstanding. These operations 
        // must not block the application.
            dispatch_recursive(TRUE);
        }
// Continue with operations you want to be carried out only after 
// the asynchronous operation has finished.
...

In this example, attribute values in the MIS for all Image instances in an object collection are updated asynchronously. To ensure that the dispatch_recursive function of the sched scheduler is called only while this operation is still unfinished, it is called in a loop while the was_completed function returns FALSE.

8.3.5 Adding a Callback to the Scheduler Queue

Add a callback to the scheduler queue when you want the callback to be run. Adding a callback to the scheduler queue enables you to specify data that the scheduler passes to your callback when the callback is run.

You only need to add a callback to the scheduler queue if you are implementing an asynchronous function yourself. You do not need to add a callback to the scheduler queue if you are using the asynchronous functions supplied in the Solstice EM APIs.

Adding a callback to the scheduler queue involves:

In the call to send_resp, specify a pointer to the data that the scheduler passes to the callback when the callback is run. Your callback must include code for converting the data into a CurrentEvent instance when the callback is run. If you want to process the data, in your callback, call functions of the CurrentEvent class for processing the data. For more information, refer to Section 8.3.3.3 Writing Code for Handling Responses From Managed Objects.

8.4 Verifying and Changing the Status of an Asynchronous Operation

To verify or change the status of an asynchronous operation, use the instance of the Waiter class returned by the function you called to initiate the asynchronous operation. The instance of Waiter returned enables you verify or change the status of an asynchronous operation by:

8.4.1 Verifying the Result of an Asynchronous Operation

To enable your application to take different actions depending on whether an asynchronous operation succeeds, verify the result of the operation. For example, verify the result of an asynchronous operation to notify the user, or take some other recovery action, if the operation fails.

To verify the result of an asynchronous operation, call the get_except function of the Waiter class.

The get_except function returns one of the following:

The value returned by the get_except function is valid only while the operation is outstanding.


Note – The procedure for verifying the result of an asynchronous operations is different from that for asynchronous operations described in Section 4.1.2 Using the get_error_type Function. The get_error_type and get_error_string functions of the Waiter class return information about functions of the Waiter class, not about the operation represented by the instance of Waiter.

To obtain information on why an asynchronous operation failed, call functions of the ExceptionType class as follows:

Code for verifying the result of an asynchronous operation is shown in CODE EXAMPLE 8-11.

CODE EXAMPLE 8-11   Verifying the Result of an Asynchronous Operation 
...
#include <pmi/hi.hh>              // High Level PMI
...
// WARNING: get_except() returns a 0 pointer if operation successful.
// Following code can also trigger segmentation faults if error occurs
// with SEM 3.0. Bottom line: AVOID USE OF ASYNC FUNCTIONALITY
    if (cell_waiter.get_except()) {
        fprintf(stderr, "Waiter: Exception: %s, Reason: %s\n",
            (cell_waiter.get_except())->name(),
            (cell_waiter.get_except())->reason());
    }

If the asynchronous operation represented by the instance of Waiter named cell_waiter fails, an error message is written to stderr. The text returned by the calls to the name and reason functions of ExceptionType is incorporated in the message written to stderr.

8.4.2 Cancelling an Asynchronous Operation

Cancel an asynchronous operation that you no longer require to be completed.

To cancel an outstanding asynchronous operation, call the cancel function of the Waiter class.

8.4.3 Changing the Timeout of an Asynchronous Operation

The timeout of an asynchronous operation specifies the maximum length of time an application allows for an asynchronous operation to finish. If an asynchronous operation is not completed within this length of time, the operation is cancelled.

Change the timeout of an asynchronous operation if you want the timeout to change in response to an event. For example, if your application is waiting for several events, change the timeout each time an event is received so that your application only times out if the interval between events exceeds some threshold.

To change the timeout of an asynchronous operation, call the waitmore function of the Waiter class. In the call to the Waitmore function, you have to specify the timeout. The timeout is a typedef double that represents the length of the timeout in seconds.

Code for changing the timeout of an asynchronous operation is given in CODE EXAMPLE 8-12.

CODE EXAMPLE 8-12   Changing the Timeout of an Asynchronous Operation 
...
#include <pmi/hi.hh>           // High Level PMI
...
// Nonblocking Example (note: boot_cb not shown in this example):
        Waiter waiter1 = cell_image.start_create(Callback(boot_cb, 0));
        waiter1.waitmore(3.0); // Specify 3 sec. timeout for creation operation
...

In this example, the timeout for an asynchronous operation to add a managed object to an MIS is changed to 3.0 seconds.


Sun Microsystems, Inc.
Copyright information. All rights reserved.
Doc Set  |   Contents   |   Previous   |   Next   |   Index