Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

Example

Component IDL

Code Block
languagecpp
titleAsync.idl
linenumberstrue
collapsetrue
#ifndef _ASYNC_IDL_
#define _ASYNC_IDL_
 
#pragma prefix "acs"
 
#include <acscommon.idl>
#include <acscomponent.idl>
 
module examples
{
    interface MyCallback: ACS::OffShoot {
        void update(in string text);
    };

    interface Async : ACS::ACSComponent {
        oneway void delayAsync(in ACS::uLong delay, in MyCallback cb);
    };

    interface Async : ACS::ACSComponent {
        void delay(in ACS::uLong delay);
    };
};
#endif

Component Implementation

C++

Code Block
languagecpp
titleAsyncImpl.h
linenumberstrue
collapsetrue
#ifndef _ASYNC_IMPL_H
#define _ASYNC_IMPL_H
 
#include <acscomponentImpl.h>
#include <AsyncS.h>
 
class AsyncImpl : public virtual acscomponent::ACSComponentImpl, public virtual POA_examples::Async
{
  public:
    AsyncImpl(const ACE_CString& name, maci::ContainerServices* containerServices);
    virtual ~AsyncImpl();
    void delayAsync(ACS::uLong delay, acs::examples::MyCallback_ptr cb);
};
#endif
Code Block
languagecpp
titleAsyncImpl.cpp
linenumberstrue
collapsetrue
#include <AsyncImpl.h>
#include <ACSErrTypeOK.h>
 
AsyncImpl::AsyncImpl(const ACE_CString& name, maci::ContainerServices* containerServices) : acscomponent::ACSComponentImpl(name, containerServices) {
}
 
AsyncImpl::~AsyncImpl() {
}
 
void AsyncImpl::delayAsync(ACS::uLong delay, acs::examples::MyCallback_ptr cb) {
    cb->update("WORKING");
    sleep(delay);
    cb->update("DONE");
}
 
/* --------------- [ MACI DLL support functions ] -----------------*/
#include <maciACSComponentDefines.h>
MACI_DLL_SUPPORT_FUNCTIONS(AsyncImpl)
/* ----------------------------------------------------------------*/

Configuration

Code Block
languagexml
titleComponents.xml
linenumberstrue
collapsetrue
<e Name="ASYNC_CPP"
   Code="AsyncImpl"
   Type="IDL:acs/examples/Async:1.0"
   Container="bilboContainer"
   ImplLang="cpp"
   KeepAliveTime="0"
/>
<e Name="ASYNC_CLIENT_CPP"
   Code="AsyncClientImpl"
   Type="IDL:acs/examples/AsyncClient:1.0"
   Container="bilboContainer"
   ImplLang="cpp"
   KeepAliveTime="0"
/>

Client Implementation

Callback Definition

C++

Code Block
languagecpp
titleMyCBImpl.h
linenumberstrue
collapsetrue
#ifndef _MY_CB_IMPL_H
#define _MY_CB_IMPL_H

#include <AsyncC.h>

class MyCBImpl : public virtual POA_examples::MyCallback {
  public:
    MyCBImpl() {
        status=std::string("INIT");
    }
    virtual ~CBuLongImpl() {}
    void update(const char* value) {
        status = std::string(value);
    }
  public:
    std::string status;
};
#endif


Standalone Client

C++

Code Block
languagecpp
titleAsyncClient.cpp
linenumberstrue
collapsetrue
#include <maciSimpleClient.h>
#include <AsyncC.h>
#include <ACSErrTypeCommon.h>
#include <acsutilTimeStamp.h>
#include <MyCBImpl.h>

using namespace maci;
  
int main(int argc, char *argv[]) {
    SimpleClient client;
    examples::Async_var comp;
  
    if (client.init(argc,argv) == 0) {
        return -1;
    } else {
        client.login();
    }
  
    try {
        comp = client.getComponent<examples::Async>("ASYNC_CPP", 0, true);
    } catch(maciErrType::CannotGetComponentExImpl& _ex) {
        _ex.log();
        return -1;
    }
  
    MyCBImpl cb;
    examples::MyCallback_var cbObj = cb._this();
  
    ACS_SHORT_LOG((LM_INFO, "%s", cb.status));
    comp->delayAsync(8, cbObj.in());
  
    ACS_SHORT_LOG((LM_INFO, "%s", cb.status));
    sleep(5);
    ACS_SHORT_LOG((LM_INFO, "%s", cb.status));
    sleep(5);
  
    ACS_SHORT_LOG((LM_INFO, "%s", cb.status));
  
    try {
        client.releaseComponent("ASYNC_CPP");
    } catch(maciErrType::CannotReleaseComponentExImpl &_ex) {
        _ex.log();
        return -1;
    }
  
    client.logout();
  
    ACE_OS::sleep(3);
    return 0;
}

Component Client

C++

Code Block
languagecpp
titleAsyncClientImpl.h
linenumberstrue
collapsetrue
#ifndef _ASYNC_CLIENT_IMPL_H
#define _ASYNC_CLIENT_IMPL_H
 
#include <acscomponentImpl.h>
#include <AsyncS.h>
 
class AsyncClientImpl : public virtual acscomponent::ACSComponentImpl, public virtual POA_examples::AsyncClient
{
  public:
    AsyncClientImpl(const ACE_CString& name, maci::ContainerServices* containerServices);
    virtual ~AsyncClientImpl();
    void delay(ACS::uLong delay);
};
#endif
Code Block
languagecpp
titleAsyncClientImpl.cpp
linenumberstrue
collapsetrue
#include <AsyncClientImpl.h>
#include <ACSErrTypeOK.h>
 
AsyncClientImpl::AsyncClientImpl(const ACE_CString& name, maci::ContainerServices* containerServices) : acscomponent::ACSComponentImpl(name, containerServices) {
}
 
AsyncClientImpl::~AsyncClientImpl() {
}
 
void AsyncClientImpl::delay(ACS::uLong delay) {
    examples::Async_var comp = getContainerServices().getComponent<examples::Async>("ASYNC_CPP", 0, true);

    MyCBImpl cb;
    ACS::OffShoot_var offshoot = getContainerServices().activateOffShoot(&cb);
    examples::MyCallback_var cbObj = examples::MyCallback::_narrow(offshoot);

    ACS_SHORT_LOG((LM_INFO, "%s", cb.status));
    comp->delayAsync(delay, cbObj.in());
    ACS_SHORT_LOG((LM_INFO, "%s", cb.status));
    sleep(delay/2+1);
    ACS_SHORT_LOG((LM_INFO, "%s", cb.status));
    sleep(delay/2+1);
    ACS_SHORT_LOG((LM_INFO, "%s", cb.status)); 

    getContainerServices().releaseComponent("ASYNC_CPP");
    getContainerServices().deactivateOffShoot(&cb)
}
 
/* --------------- [ MACI DLL support functions ] -----------------*/
#include <maciACSComponentDefines.h>
MACI_DLL_SUPPORT_FUNCTIONS(AsyncClientImpl)
/* ----------------------------------------------------------------*/

Notes

C++

OffShoot Standalone Client

When working with standalone clients, we need to handle the servant lifecycle of the offshoots/callbacks. There are two approaches:

...

Code Block
languagecpp
linenumberstrue
collapsetrue
MyCBImpl* cb = new MyCBImpl();
examples::MyCallback_var cbObj = cb->_this();
...
// Stop ORB
... 
// Delete the heap OffShoot servant instance
delete cb;

OffShoot Component Client

When working with standalone clients in a component, we need to handle the servant lifecycle of the offshoots/callbacks. There are three approaches:

...

  • The CORBA details are encapsulated in an ACS framework method
  • A special POA is used instead of the default one, providing special policies recommended for transient CORBA objects
    • PortableServer::SYSTEM_ID
    • PortableServer::TRANSIENT
    • PortableServer::USE_ACTIVE_OBJECT_MAP_ONLY
    • PortableServer::RETAIN

It is possible to use this approach both for stack and heap variables with the same restrictions:

Stack OffShoot

For the OffShoot servant instance on the stack, you need to make sure to deactivate the OffShoot servant before cb variable goes out of scope. Here you will get compilation issues if you try to deactivate it after going out of scope.

Code Block
languagecpp
linenumberstrue
collapsetrue
MyCBImpl cb;
ACS::OffShoot_var offshoot = getContainerServices().activateOffShoot(&cb);
examples::MyCallback_var cbObj = examples::MyCallback::_narrow(offshoot.in());
...
//Deactivate the Offshoot servant
getContainerServices().deactivateOffShoot(&cb);
Heap OffShoot

For the OffShoot servant instance on the heap, you need to make sure to deactivate the OffShoot servant before destroying the cb variable. Doing it in the reverse order has undefined behavior, usually ending in segmentation fault.

Code Block
languagecpp
linenumberstrue
collapsetrue
MyCBImpl* cb = new MyCBImpl();
ACS::OffShoot_var offshoot = getContainerServices().activateOffShoot(cb);
examples::MyCallback_var cbObj = examples::MyCallback::_narrow(offshoot.in());
...
//Deactivate the Offshoot servant
getContainerServices().deactivateOffShoot(cb);

// Make sure to delete the OffShoot servant instance after deactivating the CORBA object
delete cb;